我正在尝试《函数式编程的工艺》一书中的代码示例。
我想创建一个其中包含 Int 的树,但我似乎最终创建了一个包含整数的树(请参阅下面在 GHCi 中的执行)。
如何创建一个包含 Int
的树?有没有办法在 Haskell 中编写 Int
文字?
*Chapter18> sumTree myTree
<interactive>:35:9:
Couldn't match type `Integer' with `Int'
Expected type: Tree Int
Actual type: Tree Integer
In the first argument of `sumTree', namely `myTree'
In the expression: sumTree myTree
In an equation for `it': it = sumTree myTree
下面是相应的代码:
-- A type of binary trees.
myTree = Node 2 (Nil) (Nil)
data Tree a = Nil | Node a (Tree a) (Tree a)
-- Summing a tree of integers
-- A direct solution:
sTree :: Tree Int -> Int
sTree Nil = 0
sTree (Node n t1 t2) = n + sTree t1 + sTree t2
-- A monadic solution: first giving a value of type Id Int ...
sumTree :: Tree Int -> Id Int
sumTree Nil = return 0
--sumTree (Node n t1 t2)
-- = do num <- return n
-- s1 <- sumTree t1
-- s2 <- sumTree t2
-- return (num + s1 + s2)
sumTree (Node n t1 t2) =
return n >>=(\num ->
sumTree t1 >>= (\s1 ->
sumTree t2 >>= (\s2 ->
return (num + s1 + s2))))
-- ... then adapted to give an Int solution
sTree' :: Tree Int -> Int
sTree' = extract . sumTree
-- where the value is extracted from the Id monad thus:
extract :: Id a -> a
extract (Id x) = x
最佳答案
Monomorphism restriction再次罢工!由于 myTree
没有任何参数,因此编译器会避免使其成为多态。但数字文字是多态的(没有 Int
文字,只有整数 Num
文字!),因此编译器需要决定一些 Num
类型。好吧,如果您要处理巨大的数字,Int
可能会出现问题,因此它选择 Integer
。
给myTree
一个明确的签名可以防止这种情况发生;要么使用
myTree :: Num a => Tree a
或者
myTree :: Tree Int
关于haskell - Haskell 中的 int 字面量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22984233/