首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >haskell中的Pointfree风格编程

haskell中的Pointfree风格编程
EN

Stack Overflow用户
提问于 2013-11-16 03:42:12
回答 3查看 368关注 0票数 2

我有这个功能

代码语言:javascript
复制
rulesApply :: [PhrasePair] -> Phrase ->  Phrase

rulesApply pp = try (transformationsApply "*" reflect  pp )

我想学习如何让它变得无关紧要。

代码语言:javascript
复制
try :: (a -> Maybe a) -> a -> a
try f x = maybe x id (f x)
transformationsApply :: Eq a => a -> ([a] -> [a]) -> ([([a], [a])] -> ([a] -> Maybe [a]))
transformationsApply wc f pfPair list = foldr1 orElse (map (transformationApply wc f list) pfPair)


 rulesApply pp = try (transformationsApply "*" reflect  pp )

(transformationsApply "*" reflect ) pp的类型为Eq a => ([([a], [a])] -> ([a] -> Maybe [a]))

我们看到了

代码语言:javascript
复制
try :: (a -> Maybe a) -> a -> a

因此,try将函数(a -> Maybe a)作为参数。我们看到(transformationsApply "*" reflect ) pp的返回类型是([a] -> Maybe [a])),所以我们应该能够写。

代码语言:javascript
复制
rulesApply pp = try . (transformationsApply "*" reflect) pp

但这会导致编译错误。

EN

回答 3

Stack Overflow用户

发布于 2013-11-16 04:14:40

无论何时你有一些看起来像

代码语言:javascript
复制
\x -> f (g x)

你可以把它变成

代码语言:javascript
复制
f . g

在本例中,您拥有

代码语言:javascript
复制
s          x  = f   (g                                 x  )
rulesApply pp = try (transformationsApply "*" reflect  pp )

它可以(通过将参数移动到等式的另一边)转换为

代码语言:javascript
复制
s          = \x  -> f   (g                                 x  )
rulesApply = \pp -> try (transformationsApply "*" reflect  pp )

反过来,根据我们的规则,

代码语言:javascript
复制
s          = f   . g
rulesApply = try . transformationsApply "*" reflect
票数 9
EN

Stack Overflow用户

发布于 2013-11-16 04:16:26

删除这些点相对容易,但您应该一步一步地移动。

代码语言:javascript
复制
rulesApply pp =  try ( transformationsApply "*" reflect  pp)

=== [partial application]

rulesApply pp =  try ((transformationsApply "*" reflect) pp)

=== [definition of (.)]

rulesApply pp = (try . transformationsApply "*" reflect) pp

=== [eta reduction]

rulesApply    =  try . transformationsApply "*" reflect
票数 7
EN

Stack Overflow用户

发布于 2013-11-16 03:45:32

实际上,这很简单:

代码语言:javascript
复制
rulesApply :: [PhrasePair] -> Phrase ->  Phrase
rulesApply = try . transformationsApply "*" reflect

无指针编程不仅仅关乎美学。这是关于在更高的层次上处理问题:不是对函数的变量进行操作,而是对函数本身进行操作,从而消除了整个问题领域。

让我们分析一下(.)操作符的签名。

代码语言:javascript
复制
(.) :: (b -> c) -> (a -> b) -> (a -> c)

我有意用大括号将a -> c括起来,以表明需要两个函数才能生成另一个函数。在这方面,它与原始值上的任何运算符没有太大区别,例如:

代码语言:javascript
复制
(+) :: Int -> Int -> Int

现在,不要着迷于它,也不要期望它会在你的道路上遇到任何问题。这只是你口袋里的另一个工具,应该适当地使用。它最常见的用法是避免多余的lambda。下面是一些示例:

代码语言:javascript
复制
putStrLn . (++ "!") == \a -> putStrLn (a ++ "!")

void . return == \a -> return a >> return ()

第二个示例基本上等同于const (return ()) == \a -> return (),但出于美学原因,我更喜欢它。我认为,编译器无论如何都会优化这些东西。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20009293

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档