【问题标题】:Transforming a Haskell function to a point free representaion将 Haskell 函数转换为无点表示
【发布时间】:2014-04-19 17:56:21
【问题描述】:

我想创建一个 pointfree 函数,它采用函数列表,将单个参数应用于每个列出的函数,然后通过另一个函数压缩列表。此函数的无点版本将具有以下类型签名:

multiplex :: ([a] -> b) -> [(c -> a)] -> (c -> b)

还有一个用法示例:

invariantsHold :: (Integral a) => a -> Bool
invariantsHold = multiplex (all id) [(>=0),(<=50),even]

我能够写出以下内容:

multiplex :: ([a] -> b) -> [(c -> a)] -> c -> b
multiplex f xs e = f $ map ((flip ($)) e) xs

这个实现不是无点的,我怎样才能把这个函数转换成一个无点的表示?

【问题讨论】:

  • Lambdabot 暗示了这个美丽:(. flip (map . flip id)) . (.)
  • @duplode 我一直在寻找像 thisthis 这样的记录函数转换。目标是尝试使函数更具可读性,同时减少定义中的点。 Lambdabot 的“美”虽然正确,但没有为我提供改进功能所必需的信息。
  • 我知道;这就是为什么我没有将其发布为答案的原因。无论如何,($ e) 而不是 ((flip ($)) e) 会大大提高可读性。
  • 如果你交换了[c -&gt; a]c 那么它只是(.: map . flip ($)) 其中(.:) = (.) . (.)
  • @jozefg 总是有:((.: map . flip ($)) ^&gt;) where (.:) = (.).(.); (^&gt;) = flip . flip .(.) flip

标签: haskell haskell-platform pointfree purely-functional


【解决方案1】:

不是无点风格,但肯定可以通过使用Applicative 显着简化(需要导入Control.Applicative):

multiplex f xs e = f $ xs <*> pure e

invariantsHold也可以简化一点:

invariantsHold = multiplex and [(>=0),(<=50),even]

使用sequenceA(来自Data.Traversable)是定义multiplex的另一种方式:

multiplex f xs e = f $ sequenceA xs e

而且这个定义可以用 pointfree 风格重写(由pointfree 提供):

multiplex = (. sequenceA) . (.)

multiplex = flip ((.) . (.)) sequenceA

很漂亮,但对我来说似乎毫无意义:-)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-22
    • 1970-01-01
    相关资源
    最近更新 更多