myLength :: (Num b) => [a] -> b
myLength = foldr (\_ acc -> 1 + acc) 0
这确实适用于字符串 . myLength "hello" => 5 等等 .
正如Lee在评论中提到的那样, foldr 的类型在GHC 7.10中更改为 Foldable t => (a -> b -> b) -> b -> t a -> b ,作为Foldable Traversable in Prelude Proposal的一部分,允许 foldr 用于许多不同的数据结构而不是单独的列表 . 在GHC 7.10上,那么你的函数确实会有 myLength :: (Foldable t, Num b) => t a -> b 的类型推断 . 注意 (Foldable t) => t a 如何概括 [a] .
1 回答
我认为您的类型签名可能因您的声明而过于具体 . 这是我在GHCi中得到的:
+
是Num
约束的来源 . 它仅适用于b
类型,因为acc
的类型与b
统一 . 没有进一步的限制因为我们没有对x :: a
做任何事情 .0
轻松与Num b => b
统一,除了我们掉箭之外没有任何变化 .我们引入了一个没有特定类型的参数
xs
,它很容易与[a]
统一 . 没有什么变化 . 所以我们的最终类型应该是这确实适用于字符串 .
myLength "hello" => 5
等等 .正如Lee在评论中提到的那样,
foldr
的类型在GHC 7.10中更改为Foldable t => (a -> b -> b) -> b -> t a -> b
,作为Foldable Traversable in Prelude Proposal的一部分,允许foldr
用于许多不同的数据结构而不是单独的列表 . 在GHC 7.10上,那么你的函数确实会有myLength :: (Foldable t, Num b) => t a -> b
的类型推断 . 注意(Foldable t) => t a
如何概括[a]
.HOORAY TYPES