2017-03-15 1 views
3

J'essaie d'apprendre le haschell à travers le cours "CIS 194: Introduction à Haskell 2013" et j'ai rencontré un problème avec l'exercice 2 la deuxième semaine. Je suis en train de définir ma fonction de construction en utilisant une fonction récursive auxiliaireUtiliser des fonctions anonymes dans Haskell CIS194 Semaine 2 Exercice 2

reduce :: (a -> b -> b) -> [a] -> b -> b 
reduce _ [] x = x 
reduce f (x:xs) y = reduce f xs (f x y) 

Le but de cette fonction est d'appliquer une fonction récursive sur la liste [a] à b. Ceci est parce que je veux insérer récursive une liste de ce LogMessage dans un MessageTree

build :: [LogMessage] -> MessageTree 
build [] = Node Leaf (Unknown "") Leaf 
build messages = 
    reduce (\x y -> (insert x y)) tail(messages) (Node Leaf head(messages) Leaf) 

mais quand je tente de compiler, je reçois une longue liste d'erreurs de compilation:

LogAnalysis.hs:42:22: 
    Couldn't match expected type `t0 -> MessageTree' 
       with actual type `MessageTree' 
    In the return type of a call of `insert' 
    Probable cause: `insert' is applied to too many arguments 
    In the expression: (insert x y) 
    In the first argument of `reduce', namely `(\ x y -> (insert x y))' 

LogAnalysis.hs:42:31: 
    Couldn't match expected type `MessageTree' 
       with actual type `t0 -> MessageTree' 
    In the second argument of `insert', namely `y' 
    In the expression: (insert x y) 
    In the first argument of `reduce', namely `(\ x y -> (insert x y))' 

LogAnalysis.hs:42:35: 
    Couldn't match expected type `[LogMessage]' 
       with actual type `[a0] -> [a0]' 
    In the second argument of `reduce', namely `tail' 
    In the expression: 
     reduce 
     (\ x y -> (insert x y)) 
     tail 
     (messages) 
     (Node Leaf head (messages) Leaf) 
    In an equation for `build': 
     build messages 
      = reduce 
       (\ x y -> (insert x y)) 
       tail 
       (messages) 
       (Node Leaf head (messages) Leaf) 

LogAnalysis.hs:42:40: 
    Couldn't match expected type `t0 -> MessageTree' 
       with actual type `[LogMessage]' 
    In the third argument of `reduce', namely `(messages)' 
    In the expression: 
     reduce 
     (\ x y -> (insert x y)) 
     tail 
     (messages) 
     (Node Leaf head (messages) Leaf) 
    In an equation for `build': 
     build messages 
      = reduce 
       (\ x y -> (insert x y)) 
       tail 
       (messages) 
       (Node Leaf head (messages) Leaf) 

LogAnalysis.hs:42:51: 
    Couldn't match expected type `MessageTree -> t0' 
       with actual type `MessageTree' 
    The function `Node' is applied to four arguments, 
    but its type `MessageTree 
       -> LogMessage -> MessageTree -> MessageTree' 
    has only three 
    In the fourth argument of `reduce', namely 
     `(Node Leaf head (messages) Leaf)' 
    In the expression: 
     reduce 
     (\ x y -> (insert x y)) 
     tail 
     (messages) 
     (Node Leaf head (messages) Leaf) 

LogAnalysis.hs:42:61: 
    Couldn't match expected type `LogMessage' 
      with actual type `[a1] -> a1' 
    In the second argument of `Node', namely `head' 
    In the fourth argument of `reduce', namely 
     `(Node Leaf head (messages) Leaf)' 
    In the expression: 
     reduce 
     (\ x y -> (insert x y)) 
     tail 
     (messages) 
     (Node Leaf head (messages) Leaf) 

LogAnalysis.hs:42:66: 
    Couldn't match expected type `MessageTree' 
      with actual type `[LogMessage]' 
    In the third argument of `Node', namely `(messages)' 
    In the fourth argument of `reduce', namely 
     `(Node Leaf head (messages) Leaf)' 
    In the expression: 
     reduce 
     (\ x y -> (insert x y)) 
     tail 
     (messages) 
     (Node Leaf head (messages) Leaf) 
Failed, modules loaded: Log. 

Pour référence, voici ma fonction d'insertion, qui compile correctement

insert :: LogMessage -> MessageTree -> MessageTree 
insert (Unknown _) tree = tree 
insert _ [email protected](Node _ (Unknown _) _) = tree 
insert message Leaf = Node Leaf message Leaf 
insert [email protected](LogMessage _ timeStampMessage _) (Node left [email protected](LogMessage _ timeStampTree _) right) 
    | timeStampMessage < timeStampTree = Node (insert message left) m right 
    | timeStampMessage > timeStampTree = Node left m (insert message right) 
    | timeStampMessage == timeStampTree = Node left message right 
+2

'(\ x y -> (insérer x y))' est équivalent à 'insert'. – chepner

Répondre

3

Les parenthèses n'indiquent pas les appels de fonction; ils affectent simplement la précédence de l'opérateur. L'application de la fonction est représentée par juxtaposition (ce qui peut être considéré comme l'opérateur avec la plus haute priorité).

Cette ligne

build messages = reduce (\x y -> (insert x y)) tail(messages) (Node Leaf head(messages) Leaf) 

doit d'abord être raccourcies à

build messages = reduce insert tail(messages) (Node Leaf head(messages) Leaf) 

ce qui le rend plus facile de voir la bonne façon de parenthésée:

build messages = reduce insert (tail messages) (Node Leaf (head messages) Leaf) 

Ceci est cependant mieux écrit en utilisant la correspondance de modèle que d'utiliser head et tail:

build (x:xs) = reduce insert xs (Node Leaf x Leaf)