pointfree添加到haskell中的列表

时间:2016-03-08 10:12:20

标签: haskell pointfree

我试图使用简单的函数链来导出三个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]

2 个答案:

答案 0 :(得分:3)

让我们看一下更通用的版本,它使用三个函数fgh

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

现在我们要做的就是插入fgh的定义:

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