我正在尝试理解如何在Haskell中将函数转换为无指针表示法。我看到了this example,但它比我要找的复杂得多。我觉得我理解它背后的逻辑,但当我试图在代码中执行一些简单的示例时,我得到了编译错误。我想试着用无指针的方式编写这个函数:
我将其重新编排为f x = (+) 5 $ (/) 8 x的f x = 5 + 8/x
所以,我想可能是这样的:
f = (+) 5 $ (/) 8但是当我在ghci中运行这段代码时,我得到了这样的消息:
No instance for (Num (a0 -> a0))
arising from the literal `5' at Test.hs:3:9
Possible fix: add an instance declaration for (Num (a0 -> a0))
In the first argument of `(+)', namely `5'
In the first argument of `($)', namely `(+) 5'
In the expression: (+) 5 $ (/) 8
Failed, modules loaded: none.我不明白“没有实例...”消息。要以无指针的方式编写此函数,我需要做些什么?
发布于 2011-12-12 00:39:21
$的优先级非常低。所以,f x = (+) 5 $ (/) 8 x实际上是指f x = (+) 5 $ ((/) 8 x)。相反,将其重写为
f x = (+) 5 ( (/) 8 x)
f x = ((+) 5) ( ((/) 8) x)
f x = ((+) 5) . ( ((/) 8) ) x
f = ((+) 5) . ( (/) 8 )
f = (5+) . (8/)最后一个表达式是有意义的:F是两个操作的组合,首先将8除以1,然后将结果加5。记住,g.h的意思是“应用h,然后应用g的结果”。
发布于 2011-12-12 00:43:15
“无点”程序可以与cabal install pointfree一起安装,它向您展示了如何以无点风格编写表达式。例如:
$ pointfree "f x = 5 + 8/x"
f = (5 +) . (8 /)此转换的说明:
(+ a) == \b -> b + a(a +) == \b -> a + b .函数获取第二个参数的结果,并将其应用于第一个参数。发布于 2011-12-12 07:01:18
从λ演算(哈斯克尔是其变体)术语到SKI术语(完全无点函数,仅使用const (K),id (I)和<*> (S))的转换可以使用以下简单规则完成:
\x -> x转换为id;\x -> y,而\x -> g.中没有出现x转换为y转换为f' <*> g',其中\x -> g.是x的翻译,y是f' <*> g'的翻译
现在你可能想知道.是从哪里来的。最后一次转换有一个特殊情况:如果f没有任何空闲的x,那么\x -> f g将转换为const f <*> (\x -> g),它等于f . (\x -> g)。
使用这些规则,我们可以转换您的函数:
f = \x -> ((+) 5) (((/) 8) x) = -- by the special-case (.) rule
((+) 5) . (\x -> (((/) 8) x)) = -- by eta-reduction ((\x -> f x) = f)
((+) 5) . ((/) 8)Eta减少并不是完成翻译所必需的,但如果没有它,我们会得到更混乱的东西。例如,最后一步将生成((+) 5) . ((/) 8) . id。
https://stackoverflow.com/questions/8465575
复制相似问题