如何用一元函数组成二元函数?

ice*_*man 13 haskell function-composition

我觉得我忽略了一些完全明显的东西,但是使用无点符号来组成二元函数和一元函数的正确方法(如果有的话)是什么?例如,以下代码编译:

sortedAppend :: (Ord a) -> [a] -> [a] -> [a]
sortedAppend xs ys = sort $ xs ++ ys
Run Code Online (Sandbox Code Playgroud)

但以下代码无法编译:

sortedAppend :: (Ord a) -> [a] -> [a] -> [a]
sortedAppend = sort . (++)
Run Code Online (Sandbox Code Playgroud)

难道我们能够组成(++)sort(按顺序如上图所示)?如果是这样,怎么样?

jam*_*idh 18

我不认为任何这些解决方案(我的或其他)都很漂亮,但我更喜欢....

let sortedAppend = (sort .) . (++)
Run Code Online (Sandbox Code Playgroud)

我更喜欢这个的原因是因为我很容易想到......如果忽略括号,你基本上需要为每个参数添加一个额外的(.)

f . g --one parameter
f . . g --two params
f . . . g --three params
Run Code Online (Sandbox Code Playgroud)

这是有道理的,因为g x返回一个N-1输入的功能....

....但是那些需要的parens让它变得如此丑陋....

((f .) .) . g
Run Code Online (Sandbox Code Playgroud)

  • [SEC](http://conal.net/blog/posts/semantic-editor-combinators)透视:`result =(.)`,然后`result fg`,`(result.result)fg`,`( result.result.result)fg` (2认同)

Car*_*ten 12

可以使用"owl-operator"(我认为有时也称为breast.operator):

Prelude> :t (.).(.)
(.).(.) :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c
Run Code Online (Sandbox Code Playgroud)

但是:我认为你不应该 - 你所写的内容非常易读 - 使用这个:

sortedAppend = ((.).(.)) sort (++)
Run Code Online (Sandbox Code Playgroud)

不是国际海事组织

PS:是的,你可以做到

(.:.) = (.).(.)
sortedAppend = sort .:. (++)
Run Code Online (Sandbox Code Playgroud)

但仍然......不易消化

PPS:我刚刚发现这个运算符被定义为(.:)一个名为pointless-fun ^^ 的包

  • 另一种可能性:`sortedAppend xs = sort.(xs ++)` (5认同)
  • 更通用的形式`(.).(.)`是`fmap fmap fmap`.请记住,这可以变成```fmap`fmap`fmap```,相当于`fmap.fmap`,但我最喜欢第一个版本.这将让你做一些像`(+ 1).:[Just 1,Nothing,Just 2]`并获得`[Just 2,Nothing,Just 3]`或类似`sequence $ length.:replicate 3 getLine `(可能更好的是`fmap length $ replicateM 3 getLine`),但运算符还有其他用途.基本上它所做的就是将一个函数2"Functor"层映射到深层. (3认同)

Lub*_*lář 10

只是为了完整起见,让我们实际上以你的榜样为例,逐渐让它自由.

首先,请记住(f . g) x = f (g x).然后是Eta减少(\x -> f x) ? f.最后有用的是操作员部分.使用这些规则我们可以这样:

sortedAppend xs ys = sort $ xs ++ ys        -- original function
sortedAppend xs ys = sort (xs ++ ys)        -- remove $
sortedAppend xs ys = sort ((++) xs ys)      -- prefix application of ++
sortedAppend xs ys = (sort . ((++) xs)) ys  -- definition of composition
sortedAppend xs = sort . (++) xs            -- eta reduction
sortedAppend xs = (sort .) ((++) xs)        -- operator section
sortedAppend xs = ((sort .) . (++)) xs      -- definition of composition
sortedAppend = (sort .) . (++)              -- eta reduction
Run Code Online (Sandbox Code Playgroud)


Joa*_*ner 8

我不认为我个人建议为这样的事情添加依赖项,但也有

(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
Run Code Online (Sandbox Code Playgroud)

Data.Composition包中composition.