Haskell 最好的方法是什么;如果“是”,则替换;?
我正在考虑一个函数,当Haskell 最好的方法是什么;如果“是”,则替换;?,haskell,pointfree,Haskell,Pointfree,我正在考虑一个函数,当x为y时,它可以用z替换x的值,而不做任何其他操作,即: \x -> if x == y then z else x 它只在我的程序中使用过一次,它在一个函数链的中间,所以我不想把它定义为一个命名函数,我认为lambda表达式看起来不必要冗长。相反,我试图从其他函数中组合它。然而,到目前为止,我只想出了一个神秘的(而且令人啼笑皆非的)答案: 对于这样一个简单的函数,有更好的无点形式吗?我不太赞成这一点,但一个快速的提示让我找到了包中的操作符。这个包中充满了这样的函数
x
为y
时,它可以用z
替换x
的值,而不做任何其他操作,即:
\x -> if x == y then z else x
它只在我的程序中使用过一次,它在一个函数链的中间,所以我不想把它定义为一个命名函数,我认为lambda表达式看起来不必要冗长。相反,我试图从其他函数中组合它。然而,到目前为止,我只想出了一个神秘的(而且令人啼笑皆非的)答案:
对于这样一个简单的函数,有更好的无点形式吗?我不太赞成这一点,但一个快速的提示让我找到了包中的操作符。这个包中充满了这样的函数(还有一堆关于“非惯用haskell”的免责声明)。看来你可以
\x -> if x == y then z else x -- the cluttered Haskell form
\x -> x ?| (/= y) $ z -- the "Pythonic" form
(?| (/= y)) z -- Haskell-sections-galore of the "Pythonic" form
撇开玩笑不谈,还有一种更合理的方式,你可能会喜欢:
fromBoolC z (/= y)
我不太赞成这一点,但一个快速引导我找到了包裹中的接线员。这个包中充满了这样的函数(还有一堆关于“非惯用haskell”的免责声明)。看来你可以
\x -> if x == y then z else x -- the cluttered Haskell form
\x -> x ?| (/= y) $ z -- the "Pythonic" form
(?| (/= y)) z -- Haskell-sections-galore of the "Pythonic" form
撇开玩笑不谈,还有一种更合理的方式,你可能会喜欢:
fromBoolC z (/= y)
发件人:
不过,if-then-else
版本肯定更好。来自:
不过,
if-then-else
版本肯定更好。我不知道有什么可读性很强的。我能得到的最短的是
bool z <*> (/= y)
bool z(/=y)
其他愚蠢的方式:
execState (gets (==y) >>= flip when (put z))
fromMaybe <*> flip lookup [(y, z)]
execState(get(=y)>>=flip when(put z))
from翻转查找[(y,z)]
我不知道有什么可读性很强的东西。我能得到的最短的是
bool z <*> (/= y)
bool z(/=y)
其他愚蠢的方式:
execState (gets (==y) >>= flip when (put z))
fromMaybe <*> flip lookup [(y, z)]
execState(get(=y)>>=flip when(put z))
from翻转查找[(y,z)]
您可以使用Python技巧,用查找替换case语句
import Data.Map
\x -> findWithDefault x x (singleton y z)
根据pointfree.io可以将其简化为
flip (join findWithDefault) (singleton y z)
这并不十分清楚,但同时它将函数部分与参数分开flip(joinfindwithdefault)
执行您想要的操作,singletonyz
是一种类似DSL的异常指定方法。在代码的前面粘贴一个idExcept=flip(joinfindwithdefault)
和exception=singleton
,链几乎是可读的
my . awesome . (idExcept (exception y z)) . function . chain $ val
您可以使用Python技巧,用查找替换case语句
import Data.Map
\x -> findWithDefault x x (singleton y z)
根据pointfree.io可以将其简化为
flip (join findWithDefault) (singleton y z)
这并不十分清楚,但同时它将函数部分与参数分开flip(joinfindwithdefault)
执行您想要的操作,singletonyz
是一种类似DSL的异常指定方法。在代码的前面粘贴一个idExcept=flip(joinfindwithdefault)
和exception=singleton
,链几乎是可读的
my . awesome . (idExcept (exception y z)) . function . chain $ val
我认为没有什么比第一个有意义的版本更好了。@chi:是的,也许吧。但是我真的对我的
不满意。令人惊叹的(\x->如果x==y,则z=x)。作用链$val
:为什么不仅仅在where
子句中定义它呢?旁白:相当多的人不喜欢if-then-else表达式,有些人甚至希望看到它们因为多余的特殊语法而从语言中删除。然而,就我个人而言,我认为它们很好,有自己的位置——它们很紧凑,可以插入几乎任何地方,而且不像bool
那样,永远不会让你搞不清参数的顺序。如果y
是一个常量,比如42
,你可以执行(\case 42->z;x->x)
使用LambdaCase
。我认为没有什么比第一个有意义的版本更好的了。@chi:也许吧。但是我真的对我的不满意。令人惊叹的(\x->如果x==y,则z=x)。作用链$val
:为什么不仅仅在where
子句中定义它呢?旁白:相当多的人不喜欢if-then-else表达式,有些人甚至希望看到它们因为多余的特殊语法而从语言中删除。然而,就我个人而言,我认为它们很好,有自己的位置——它们很紧凑,可以插入几乎任何地方,而且不像bool
那样,永远不会让你搞不清参数的顺序。如果y
是一个常量,比如42
,你可以执行(\case 42->z;x->x)LambdaCase
。我觉得boolz(/=y)
是这些答案中最不糟糕的选择。我觉得boolz(/=y)
是这些答案中最不糟糕的选择。直接从数据的文档中。简单
:“注意:这可能不被视为良好做法。使用标准if-then-else,它几乎总是更清晰。您已经被警告过。“事实上,当存在简单易懂的基本可读选项时,我为什么要查找一个不常见的函数呢?直接从数据的文档中获取。Easy
:”注意:这可能不是好的做法。使用标准if-then-else,它几乎总是更清晰。你已经被警告过了,“事实上,当存在一个简单易读的替代方法时,我为什么要查找一个不常见的函数呢?”?