我试图使用简单的函数链来导出三个args的函数。
该功能应为
addToList :: a -> a -> a -> [a]
是
的无点类似物addToList :: a b c = (a : (b : (c : [])))
到目前为止,我已经找到了
addToList = ((.)((.) (flip (:)) . (flip (:))) . (flip (:))) []
但它反过来了:
Prelude> addToList 4 5 6
[6,5,4]
看起来很笨重。
如何才能获得像
这样的好东西(.) (.) (.) (:) (:) (: [])
的工作原理如下:
Prelude> addToList 4 5 6
[4,5,6]
答案 0 :(得分:3)
让我们看一下更通用的版本,它使用三个函数f
,g
和h
:
func a b c = f a (g b (h c))
在我们的案例中,f = (:)
,g = (:)
和h = return
,但我们可以将其用于遵循相同方案的任意三个函数:
func a b c = (f a . g b . h) c
要进行下一步,请在前缀表单中编写(.)
的第一个应用程序,以便以后更容易合并(.) (f a)
:
func a b = (.) (f a) (g b . h)
= (.) (f a) (g b . h)
= (.) (f a) ((.) (g b) h)
= (.) (f a) (flip (.) h (g b))
= (.) (f a) ((flip (.) h . g) b)
= (.) (f a) . (flip (.) h . g) b
我们现在可以对a
执行相同的操作:
func a = (.) (f a) . (flip (.) h . g)
= (.) ((.) (f a)) (flip (.) h . g)
= flip (.) (flip (.) h . g) ((.) (f a))
= flip (.) (flip (.) h . g) . (.) (f a)
= flip (.) (flip (.) h . g) . (.) . f a
由于flip (.) x
为(.x)
,我们可以摆脱flip
:
func = flip (.) (flip (.) h . g) . (.) . f
= flip (.) ((.h) . g) . (.) . f
= (.((.h) . g)) . (.) . f
现在我们要做的就是插入f
,g
和h
的定义:
func = (.((.return) . (:))) . (.) . (:)
我没有检查是否有更短的版本,但由于这与pointfree.io产生的结果相同,因此它应该或多或少是最优的。
话虽如此,如果比较
addToList = (.((.return) . (:))) . (.) . (:)
与
addToList a b c = [a, b, c]
你想在三个月内阅读哪一篇?
答案 1 :(得分:0)
只是玩这个,也许它会给你一些想法......
-- | >>> append [4,5] 6
-- [4,5,6]
append :: [a] -> a -> [a]
append = flip (flip (++) . (: []))
-- | >>> f1 4
-- [4]
f1 :: a -> [a]
f1 = (:[])
-- | >>> f2 4 5
-- [4,5]
f2 :: a -> a -> [a]
f2 = append . f1
-- | >>> f3 4 5 6
-- [4,5,6]
f3 :: a -> a -> a -> [a]
f3 = (append .) . f2
-- | >>> f4 4 5 6 7
-- [4,5,6,7]
f4 :: a -> a -> a -> a -> [a]
f4 = ((append .) .) . f3