【发布时间】:2016-10-24 16:04:15
【问题描述】:
我在函数组合和类型方面遇到了一些问题。
我想用len 组合filter(返回一个列表),它将一个列表作为参数(技术上是Foldable,但我在这里简化了)。
查看类型一切都符合预期:
> :t length
length :: Foldable t => t a -> Int
> :t filter
filter :: (a -> Bool) -> [a] -> [a]
所以现在我希望(len . filter) 的类型是
(length . filter) :: (a -> Bool) -> [a] -> Int
实际上是
> :t (length . filter)
(length . filter) :: Foldable ((->) [a]) => (a -> Bool) -> Int
看来我失去了一些论据。它是否以某种我不理解的方式包含在Foldable 要求中?
请注意,如果我进行部分应用,一切都会按预期进行:
> let myFilter = filter odd
> :t myFilter
myFilter :: Integral a => [a] -> [a]
> :t (length . myFilter)
(length . myFilter) :: Integral a => [a] -> Int
> (length . myFilter) [1,2,3]
2
【问题讨论】:
-
要获得您期望的合成类型,您正在合成的每个函数都应采用“一个”参数。我把一个放在引号中,因为所有函数都接受一个参数。查看更多here
-
请注意
(length . filter) x y是length (filter x) y而不是length (filter x y)。此外,filter实际上是一个函数,它采用 one 参数a->Bool并返回一个函数[a]->[a](回忆一下柯里化),该组合试图将其传递给length。 -
如果像
Num [a]或任何带有(->)的东西出现在约束中(即在=>的左侧),这通常表明您基本上已经创建了类型错误,但 GHC 太客气了,不能这样称呼它,因为有人可以原则上定义一些荒谬的类实例,使其合法。
标签: haskell types functional-programming function-composition combinators