我在功能构成和类型方面遇到了一些麻烦。
我想用filter
撰写len
(返回一个列表),它以列表作为参数(技术上是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
答案 0 :(得分:5)
正确的构成将是:
(length .) . filter :: (a -> Bool) -> [a] -> Int
相当于:
\pred xs -> length $ filter pred xs
如:
\> let count = (length .) . filter
\> :type count
count :: (a -> Bool) -> [a] -> Int
\> count odd [1..3]
2
\> count even [1..3]
1
答案 1 :(得分:4)
说明:
(.) :: (b -> c) -> (a -> b) -> a -> c
filter :: (m -> Bool) -> [m] -> [m]
length :: Foldable t => t n -> Int
什么是u
?
length . filter :: u
≡ (.) length filter :: u
然后我们必须解决a, b, c, t, n
:
a -> b ~ (m -> Bool) -> [m] -> [m]
b -> c ~ Foldable t => t n -> Int
接下来:
a ~ m -> Bool
b ~ Foldable t => t n
b ~ [m] -> [m]
c ~ Int
中平凡:
a = m -> Bool
b = [m] -> [m]
c = Int
我们必须从t, n
解决b ~ Foldable t => t n
,即[m] -> [m] ~ Foldable t => t n
。
t = ((->) [m])
n = [m]
因此,t n = [m] -> [m]
简单地统一。
汇总:
(.) :: Foldable ((->) [m]) =>
(([m] -> [m]) -> Int)
-> ((m -> Bool) -> [m] -> [m])
-> (m -> Bool) -> Int
filter :: (m -> Bool) -> [m] -> [m]
length :: Foldable ((->) [m]) => ([m] -> [m]) -> Int
(.) length filter :: Foldable ((->) [m]) => (m -> Bool) -> Int
了解length . filter
为什么不是您想要的更简单的方法是查看(.)
的定义。
(.) g f x = g(f x)
因此:
(.) length filter
≡ \x -> length (filter x)
我们知道filter x
不是列表。
您可以考虑的无意义版本:
(length .) . filter
filter >=> return . length
(fmap.fmap) length filter
(id ~> id ~> length) filter -- [1]
filter $* id $$ id *$ length -- [2]
lurryA @N2 (length <$> (filter <$> _1 <*> _2)) -- [3]
答案 2 :(得分:2)
使用"three laws of operator sections",我们有
((length .) . filter) x y =
(length .) (filter x) y =
(length . filter x) y =
length (filter x y)
和
((length .) . filter) =
(.) (length .) filter =
(.) ((.) length) filter =
((.) . (.)) length filter
最后一位((.).(.))
有时称为"owl operator",也称为.:
(length .: filter
)或fmap . fmap
(对于函数,{ {1}}是fmap
)。