Re: [Haskell-cafe] Trying to implement this code

Lizz Ross wrote:
Hi im new to Haskell (really just learning).
Im trying to code a function to take in a List of Strings (e.g.) [apple, orange, banana, orange, apple, orange] , and create a binary search tree containing the Strings and integers (where the integers are the number of occurrences of each word.
I think you can use something like this to get statistics about repeats:
data (Ord a, Updateable a) => BinTree a =
Leaf | Node (BinTree a) a (BinTree a)
class Updateable a where
update :: a -> a
data Word_stat = Word_stat String Int deriving Show
instance Eq (Word_stat) where
(==) (Word_stat s1 _) (Word_stat s2 _) = s1 == s2
instance Ord (Word_stat) where
(Word_stat s1 _) < (Word_stat s2 _) = s1

Am not sure about the relevance of this approach as i have very little experience with Haskell and FP. So it would be great if someone offers better solution. It's a valid approach. Rather than declare an Updateable class, I'd just have
On 2005 April 18 Monday 16:57, Dmitry Vyal wrote: the update function be a parameter of ins_in_tree. Also, the key and value types can be independent parameters of BinTree.
Why doesnt translator automatically deduce constraints in type of ins_in_tree and flat_tree functions so i need to explicitly define them? It deduces not just the constraints, but the entire type. You don't have to state the types of ins_in_tree or flat_tree at all. The following types are distinct (Ord a, Updateable a) => BinTree a -> a -> BinTree a BinTree a -> a -> BinTree a because the latter type has no constraints, and names having the latter type can be used in more contexts than the former. If foo :: BinTree a -> a -> BinTree a meant that foo might or might not have constraints, then there would be no way to tell the translator that foo has no constraints.
--------------- data (Ord a, Updateable a) => BinTree a = Leaf | Node (BinTree a) a (BinTree a)
class Updateable a where update :: a -> a
data Word_stat = Word_stat String Int deriving Show
instance Eq (Word_stat) where (==) (Word_stat s1 _) (Word_stat s2 _) = s1 == s2
instance Ord (Word_stat) where (Word_stat s1 _) < (Word_stat s2 _) = s1
instance Updateable (Word_stat) where update (Word_stat s i) = Word_stat s (i+1) -- inserts new element in the tree or updates existing one ins_in_tree :: (Ord a, Updateable a) => BinTree a -> a -> BinTree a ins_in_tree Leaf el = Node Leaf el Leaf ins_in_tree (Node left cur right) el
| el < cur = Node (ins_in_tree left el) cur right | el == cur = Node left (update cur) right | otherwise = Node left cur (ins_in_tree right el)
-- loads list of strings in the tree ins_list :: [String] -> BinTree Word_stat ins_list lst = foldl ins_in_tree Leaf (map wrap lst) where wrap :: String -> Word_stat wrap s = Word_stat s 1 --traverses the tree flat_tree :: (Ord a, Updateable a) => BinTree a -> [a] flat_tree Leaf = [] flat_tree (Node left el right) = (flat_tree left) ++ [el] ++ (flat_tree right)
-- function you probably need summary :: [String] -> [Word_stat] summary lst = flat_tree $ ins_list lst

Scott Turner wrote:
It's a valid approach. Rather than declare an Updateable class, I'd just have the update function be a parameter of ins_in_tree. Also, the key and value types can be independent parameters of BinTree.
I started to refactor my code as you suggested. I inserted update function in the middle of parameter list of ins_in_tree function. Just because this order seemed to be logical to me. ins_in_tree :: (Ord a) => BinTree a -> (a->a) -> a -> BinTree a But soon I found that i need partial parametrization in order to rewrite old ins_list: ins_list lst = foldl ins_in_tree Leaf (map wrap lst) So i had to change parameter order in ins_in_tree: ins_in_tree :: (Ord a) => (a->a) -> BinTree a -> a -> BinTree a and then wrote: ins_list lst = foldl (ins_in_tree update_stat) Leaf (map wrap lst) update_stat (Word_stat s i) = Word_stat s (i+1) That worked, but what if i would need another order somethere further? Will I have to write some kind of wrapper like ins_in_tree' a b c = ins_in_tree b a c Does better solution exist?

On 2005-04-19 at 10:26+0400 Dmitry Vyal wrote:
I started to refactor my code as you suggested. I inserted update function in the middle of parameter list of ins_in_tree function. Just because this order seemed to be logical to me. ins_in_tree :: (Ord a) => BinTree a -> (a->a) -> a -> BinTree a
But soon I found that i need partial parametrization in order to rewrite old ins_list: ins_list lst = foldl ins_in_tree Leaf (map wrap lst)
So i had to change parameter order in ins_in_tree: ins_in_tree :: (Ord a) => (a->a) -> BinTree a -> a -> BinTree a [...] That worked, but what if i would need another order somethere further?
Just use Prelude.flip:: forall c a b. (a -> b -> c) -> b -> a -> c Which leads me to my own question: in current implementations, if I have a data structure containing a function (D f, say), and from it I generate anoter (D (flip f)), and then later (D (flip (flip f))) and so on, do the flips get reduced (to nothing if there's an even number of them) when the field of D is evaluated? -- Jón Fairbairn Jon.Fairbairn at cl.cam.ac.uk

Jon Fairbairn
Which leads me to my own question: in current implementations, if I have a data structure containing a function (D f, say), and from it I generate anoter (D (flip f)), and then later (D (flip (flip f))) and so on, do the flips get reduced (to nothing if there's an even number of them) when the field of D is evaluated?
No, not as far as I can see, unless there are opportunities for static inlining (and therefore compile-time reduction). AIUI, the application of flip needs to see three arguments before it can be evaluated. Thus, in this example: let f'' = flip (flip f) appf = f'' 0 in [appf 1, appf 2, appf 3] the code for flip will run six times, whereas here: let f'' = flip (flip f) appf = f'' 0 1 in [appf 2, appf 3, appf 4] the code for flip is run only twice. The difference in the examples is that flip is only partially applied in the first case, but fully saturated in the second. At any rate, I think this is how it works in nhc98. Regards, Malcolm
participants (4)
-
Dmitry Vyal
-
Jon Fairbairn
-
Malcolm Wallace
-
Scott Turner