在 Haskell CIS194 第 2 周练习 2 中使用匿名函数
Using anonymous functions in Haskell CIS194 Week 2 Exercise 2
我正在尝试通过 "CIS 194: Introduction to Haskell 2013" 课程学习 haskell,并且 运行 在第二周的练习 2 中遇到困难。我正在尝试使用辅助递归函数定义我的构建函数
reduce :: (a -> b -> b) -> [a] -> b -> b
reduce _ [] x = x
reduce f (x:xs) y = reduce f xs (f x y)
这个函数的目标是递归地将列表[a]上的一个函数应用到b。这是因为我想递归地将 LogMessage 列表插入 MessageTree
build :: [LogMessage] -> MessageTree
build [] = Node Leaf (Unknown "") Leaf
build messages =
reduce (\x y -> (insert x y)) tail(messages) (Node Leaf head(messages) Leaf)
但是当我尝试编译它时,我收到了一长串编译错误:
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.
供参考,这是我的插入函数,它编译正确
insert :: LogMessage -> MessageTree -> MessageTree
insert (Unknown _) tree = tree
insert _ tree@(Node _ (Unknown _) _) = tree
insert message Leaf = Node Leaf message Leaf
insert message@(LogMessage _ timeStampMessage _) (Node left m@(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
括号不表示函数调用;它们只会影响运算符的优先级。函数应用用并列表示(可以认为是最高优先级的运算符)。
这一行
build messages = reduce (\x y -> (insert x y)) tail(messages) (Node Leaf head(messages) Leaf)
应首先缩短为
build messages = reduce insert tail(messages) (Node Leaf head(messages) Leaf)
这样可以更容易地看到括号的正确方法:
build messages = reduce insert (tail messages) (Node Leaf (head messages) Leaf)
但是,使用模式匹配比使用 head
和 tail
更好:
build (x:xs) = reduce insert xs (Node Leaf x Leaf)
我正在尝试通过 "CIS 194: Introduction to Haskell 2013" 课程学习 haskell,并且 运行 在第二周的练习 2 中遇到困难。我正在尝试使用辅助递归函数定义我的构建函数
reduce :: (a -> b -> b) -> [a] -> b -> b
reduce _ [] x = x
reduce f (x:xs) y = reduce f xs (f x y)
这个函数的目标是递归地将列表[a]上的一个函数应用到b。这是因为我想递归地将 LogMessage 列表插入 MessageTree
build :: [LogMessage] -> MessageTree
build [] = Node Leaf (Unknown "") Leaf
build messages =
reduce (\x y -> (insert x y)) tail(messages) (Node Leaf head(messages) Leaf)
但是当我尝试编译它时,我收到了一长串编译错误:
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.
供参考,这是我的插入函数,它编译正确
insert :: LogMessage -> MessageTree -> MessageTree
insert (Unknown _) tree = tree
insert _ tree@(Node _ (Unknown _) _) = tree
insert message Leaf = Node Leaf message Leaf
insert message@(LogMessage _ timeStampMessage _) (Node left m@(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
括号不表示函数调用;它们只会影响运算符的优先级。函数应用用并列表示(可以认为是最高优先级的运算符)。
这一行
build messages = reduce (\x y -> (insert x y)) tail(messages) (Node Leaf head(messages) Leaf)
应首先缩短为
build messages = reduce insert tail(messages) (Node Leaf head(messages) Leaf)
这样可以更容易地看到括号的正确方法:
build messages = reduce insert (tail messages) (Node Leaf (head messages) Leaf)
但是,使用模式匹配比使用 head
和 tail
更好:
build (x:xs) = reduce insert xs (Node Leaf x Leaf)