haskell 多元无点复合

vjrehmav  于 2023-01-17  发布在  其他
关注(0)|答案(4)|浏览(106)

我已经开始理解它了,我更喜欢在简单的情况下使用它,在这种情况下,我可以将值从一个输出管道传输到一个输入。

let joinLines = foldr (++) "" . intersperse "\n"

在今天使用GHCI时,我想看看是否可以组合not(==)来复制(/=),但我无法真正推理出来。(==)接受两个输入,not接受一个输入。我认为这可能会起作用:

let ne = not . (==)

假设(==)的单个Bool输出将转到not,但它不会编译,引用以下错误:

<interactive>:1:16:
    Couldn't match expected type `Bool' with actual type `a0 -> Bool'
    Expected type: a0 -> Bool
      Actual type: a0 -> a0 -> Bool
    In the second argument of `(.)', namely `(==)'
    In the expression: not . (==)

我希望我能说它对我意义重大,但我得到的只是,传递给(==)的第二个参数可能会把not的事情搞砸,有人能帮助我更好地理解这个组合背后的逻辑吗?

dgjrabp2

dgjrabp21#

如果一次只删除一个参数,则会得到

ne x y = not (x == y)
       = (not . (x ==)) y
ne x   = not . (x ==)
       = not . ((==) x)
       = ((not .) . (==)) x
ne     = (not .) . (==)

基本上,对于每个参数,都需要一个正确关联的(.)
(==)的类型是Eq a => a -> a -> Bool,所以如果你写whatever . (==),并传递一个值x,你得到whatever ((==) x),但是(==) x是一个函数a -> Bool(其中ax的类型,也是Eq的示例),所以(==)必须接受函数类型的参数。

gwo2fgha

gwo2fgha2#

另一个有用的运算符是(.:),它是一个组合子,用于初始化带有两个参数的函数:

f . g  $ x
f .: g $ x y
0s0u357o

0s0u357o3#

显式使用curryuncurry有助于在“多参数”函数和单参数函数之间切换。

ne = curry (not . uncurry (==))

uncurry“修复”(==),使其采用单个参数(x,y),而不是单独的xy参数。然后,可以按预期使用not组合生成的函数。然后,可以重新修改组合后的函数,使其再次接受单独的参数。

dw1jzc5e

dw1jzc5e4#

我不确定这是否有意义...但在我看来是可读的

ne = (.) not . (==)

相关问题