haskell - 无法获得在 Haskell 中编译的无点符号

标签 haskell pointfree function-composition

这是有效的

unique :: (a -> Bool) -> [a] -> Bool
unique p xs = 1 == length (filter p xs)

但现在我想要它的形式:

unique = (== 1) . length . filter

错误信息:

Couldn't match expected type `[a] -> Bool' with actual type `Bool'
Expected type: b0 -> [a] -> Bool
  Actual type: b0 -> Bool
In the first argument of `(.)', namely `(== 1)'
In the expression: (== 1) . length . filter

为什么这不起作用?

最佳答案

这是因为filter 是一个有两个参数的函数。你可以使用方便的运算符来解决这个问题

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

-- Important to make it the same precedence as (.)
infixr 9 .:

unique = ((== 1) . length) .: filter

如果你查看 GHCi 中 (length .) 的类型,你会得到

(length .) :: (a -> [b]) -> a -> Int

这意味着它需要一个返回列表的单参数函数。如果我们看一下 filter 的类型:

filter :: (a -> Bool) -> [a] -> [a]

这可以重写为“单个参数”

filter :: (a -> Bool) -> ([a] -> [a])

这很明显与 a -> [b] 不一致!特别是,编译器无法弄清楚如何使 ([a] -> [a])[b] 相同,因为一个是函数在列表上,另一个只是一个列表。所以这就是类型错误的来源。


有趣的是,.: 运算符可以泛化为在仿函数上工作:

(.:) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)
(.:) = fmap fmap fmap
-- Since the first `fmap` is for the (->) r functor, you can also write this
-- as (.:) = fmap `fmap` fmap === fmap . fmap

这有什么用?假设您有一个 Maybe [[Int]],并且您想要 Just 中每个子列表的总和,前提是它存在:

> let myData = Just [[3, 2, 1], [4], [5, 6]]
> sum .: myData
Just [6, 4, 11]
> length .: myData
Just [3, 1, 2]
> sort .: myData
Just [[1,2,3],[4],[5,6]]

或者如果您有一个[Maybe Int],并且您想要递增每个:

> let myData = [Just 1, Nothing, Just 3]
> (+1) .: myData
[Just 2,Nothing,Just 4]

可能性还在继续。基本上,它可以让你在两个嵌套的仿函数中映射一个函数,这种结构经常出现。如果你曾经在 Maybe 中有一个列表,或者列表中有元组,或者 IO 返回一个字符串,或者类似的东西,你会遇到这样的情况你可以在哪里使用 (.:) = fmap fmap fmap

关于haskell - 无法获得在 Haskell 中编译的无点符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25647823/

相关文章:

haskell - 理解抽象类型

haskell - 是否有惯用的pointfree方法通过另一个函数调用带参数的函数

haskell - 什么时候使用无意义的风格?

haskell - 函数组合 - Haskell

javascript - TypeScript 类 A 的方法作为 B 方法的传递

haskell - 即使您无法对新类型进行模式匹配,新类型也不会产生任何成本吗?

haskell - ghc 7.4.2,动态调用模块

haskell - 我该如何使用排序?

ruby - 如何将 Ruby 方法变成 block ?

haskell - Haskell 示例中的函数组合