如何在Haskell中使用(.)
我试图在Haskell中写下这样的东西:如何在Haskell中使用(.),haskell,pointfree,function-composition,combinators,dot-operator,Haskell,Pointfree,Function Composition,Combinators,Dot Operator,我试图在Haskell中写下这样的东西: length . nub . intersect 但它不起作用 *Main Data.List> :t intersect intersect :: Eq a => [a] -> [a] -> [a] *Main Data.List> :t nub nub :: Eq a => [a] -> [a] *Main Data.List> :t length length :: [a] -> Int 根
length . nub . intersect
但它不起作用
*Main Data.List> :t intersect
intersect :: Eq a => [a] -> [a] -> [a]
*Main Data.List> :t nub
nub :: Eq a => [a] -> [a]
*Main Data.List> :t length
length :: [a] -> Int
根据类型,我的理解是,
intersect
返回一种类型的[a]
,并捐赠给nub
,后者正好获取一种类型的[a]
,然后还将一种类型的[a]
返回到长度,最后返回的应该是Int
。有什么问题吗?这里的问题是,intersect
接受两个参数(在某种意义上)
您可以显式提供其中一个参数:
> let f a = length . nub . intersect a
> :t f
f :: Eq a => [a] -> [a] -> Int
或者你可以使用一个有趣的小操作符,比如(.:)=(。()
:
这是一个您不需要parens的版本:
导入数据。列表
infixr 9 .:
(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
(.:) = (.).(.)
f :: Eq a => [a] -> [a] -> Int
f = length .: nub .: intersect
我猜这是基于你上一个问题中的评论,在哪里
首先,length。核心。intersect
无法工作。你的类型是:
(.) :: (b -> c) -> (a -> b) -> (a -> c)
length :: [a] -> Int
nub :: Eq a => [a] -> [a]
intersect :: Eq a => [a] -> [a] -> [a] ~ [a] -> ([a] -> [a])
正如您所看到的,intersect
的类型是错误的,在()
的上下文中,类型参数b
将被([a]->[a])
替换,这不是nub
的第一个参数的类型。我要说的是:首先以“哑”的方式编写代码,然后重构它以使用()
。经过一些实践后,合成操作符将变得像第二天性
所以你首先要写:
yourFunction xs ys = length (nub (intersect xs ys))
()
允许您做的是(从语法上)去掉最里面函数的最后一个参数,即所有参数。在本例中,参数为ys
:
yourFunction xs = length . nub . intersect xs
实际上,intersect
返回一种类型的[a]->[a]
<代码>((length.nub)。)。intersect将执行您想要的操作,但我的理解力太弱,无法回答。另请参见:哦,对了!谢谢它基于前一个问题;)谢谢我现在终于明白了“.”现在意味着什么!
yourFunction xs = length . nub . intersect xs