【问题标题】:How to use (.) in Haskell如何在 Haskell 中使用 (.)
【发布时间】:2014-11-02 11:51:20
【问题描述】:

我正在尝试在 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

根据类型,我的理解是 intersect 返回一个 [a] 的类型并捐赠给 nub ,它正好接受一个 [a] 的类型,然后也返回一个 [a] 的类型给@ 987654329@,那么最后返回应该是Int。它有什么问题?

【问题讨论】:

  • 其实intersect返回的类型是[a] -> [a]((length . nub) .) . intersect 会做你想做的,但我这里的理解太弱,无法回答。

标签: haskell pointfree function-composition combinators dot-operator


【解决方案1】:

这里的问题是intersect 需要2个参数(在某种意义上)

您可以显式提供参数之一:

> let f a = length . nub . intersect a
> :t f
f :: Eq a => [a] -> [a] -> Int

或者你可以使用一个有趣的小运算符,比如(.:) = (.) . (.)

> let (.:) = (.) . (.)
> :t length .: (nub .: intersect)
length .: (nub .: intersect) :: Eq a => [a] -> [a] -> Int

这是一个不需要括号的版本:

导入数据列表

infixr 9 .:

(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
(.:) = (.).(.)

f :: Eq a => [a] -> [a] -> Int
f = length .: nub .: intersect

【讨论】:

  • 谢谢!我现在终于明白“.:”是什么意思了!
【解决方案2】:

我猜这是基于您上一个问题中的 cmets,其中@CarstenKönig mentions (.) . (.)

首先,length . nub . 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 的类型第一个参数。

【讨论】:

  • 哦,对了!谢谢!它基于前一个问题;)
【解决方案3】:

我会这样说:首先以“愚蠢”的方式编写代码,然后将其重构为使用(.)。经过一些练习,组合运算符将变得像第二天性。

所以你要先写:

yourFunction xs ys = length (nub (intersect xs ys))

(.) 让你做的是摆脱(语法上)最内层函数的最后一个参数,所有的括号。在这种情况下,参数是ys:

yourFunction xs = length . nub . intersect xs

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-09
    • 2015-09-20
    • 2017-09-17
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多