如何定义多重复合函数?

2024-03-03

有没有一种方法可以定义一个 Haskell 函数,它接受函数(某种集合)并生成单个函数:它们从右到左的组合?

I tried:

foldr ($)

但这只接受其结果与其参数具有相同类型的函数列表:

foldr ($) :: a -> [a -> a] -> a

所以,我可以这样做:

foldr ($) 5 [(+) 1, (*) 2]这会产生正确的结果 11

然而尝试评估这一点:

foldr ($) "hello" [(+) 1, length]

产生以下错误:

错误 - 列表中的类型错误

*** Expression : [(1 +),length] *** Term : length *** Type : [a] -> Int *** Does not match : Int -> Int


与往常一样,让我们​​将类型注释放在各处。

-- foldr ($) "hello" [(+) 1, length]
($) :: (a -> b) -> a -> b
"hello" :: [Char]
(+) 1 :: Num a => a -> a
length :: [a] -> Int
[(+) 1, length] :: ?!

本机 Haskell 列表不能包含不同类型的项目。

那么让我们退后一步。我会用< and >表示“我们想要的列表式的东西”。我们不想要随机类型的集合。< (+) 1, length >没关系,但是< length, (+) 1 >不是,或者更确切地说我们需要一个实例Num [a]。类似地,如果我们有两个以上的项目:每个项目的类型必然与其邻居相关。此外,整个列表的类型仅与第一个和最后一个成员的类型相关:起始和结束类型是什么?

我们可以使用 GADT 来做到这一点:

{-# LANGUAGE GADTs #-}
module SO26565306 where

data F a b where
  FNil :: F a a
  (:&) :: (b -> c) -> F a b -> F a c

infixr 5 :&

runF :: F a b -> a -> b
runF FNil = id
runF (f :& fs) = f . runF fs

f :: F [a] Int
f = (+) 1 :& length :& FNil

ghci> runF f "hello"
6

价值f是你想要的实现< (+) 1, length > "list".

还有一些进一步的阐述F可能的 -Functor and Category例如,但我真的不认为它有多大用处。我们所做的只是在普通函数组合上人为地强加了一种数据结构。我们甚至不能使用 GHC重载列表表示法 https://ghc.haskell.org/trac/ghc/wiki/OverloadedLists,这(还?)不够灵活。此外,插入所有 GADT 构造函数将阻止优化,几乎肯定包括列表融合。 (我没有仔细实验或思考过。)

回答你的问题

是的,可以定义一个 Haskell 函数,它接受不同但可组合类型的函数集合,并生成它们的组合。我演示的集合类型需要GADTs扩展名,即不适用于拥抱 https://stackoverflow.com/questions/11158023/how-to-use-gadts-in-hugs,您似乎正在使用的编译器。此外,您实际上无法对集合做太多事情。我还没有证明这一点,但我会断言,你无法对 type 的值做任何事情F a b你不能用 type 的值来做a -> b,而不是通过模式匹配将其分解为其组件函数。

换句话说,你所问的问题确实可以在 Haskell 中表达,只是不清楚以这种方式这样做有什么好处。

其他问题

正如我们在评论中讨论的那样,您似乎正在寻找 Clojure 传感器的 Haskell 类比。您想就该主题提出一个新问题吗?它比这个更精确,重点也不同。

底线

为什么不直接使用((+) 1) . length?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何定义多重复合函数? 的相关文章

  • 是否可以列出派生 Generic 的记录数据类型中字段的名称和类型?

    我知道对于派生 Data Data 的数据类型 constrFields http hackage haskell org package base 4 7 0 2 docs Data Data html v constrFields给出字
  • 使用 ocaml List.fold_left 列表中的最后一个元素

    我可以通过以下代码找到列表的最后一个元素 let last xs a list a let rec aux xs prev match xs with gt prev x ys gt aux ys x in match xs with gt
  • Haskell/GHC:使用相同模式匹配多个一元构造函数

    所以我正在尝试定义 TrieSet 数据类型 尽管我知道我不需要 http hackage haskell org package TrieMap module Temp where import Data Map data TrieSet
  • python函数返回函数[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何在 Yesod 中使用 CSS 框架?

    我想将 Blueprint CSS 框架与 Yesod 一起使用 有没有最佳实践 因为 Yesod 使用 CSS 模板 所以在我看来我不能直接使用 css 文件 我必须将它们重命名为 lucius files 吗 如何将 CSS 添加到 d
  • f# 运行总计序列

    好吧 这看起来应该很容易 但我就是不明白 如果我有一个数字序列 如何生成由运行总计组成的新序列 例如 对于序列 1 2 3 4 我想将其映射到 1 3 6 10 以适当的功能方式 Use List scan https msdn micro
  • 类 GADT 类型变量的未来角色?

    A 昨天的问题 https stackoverflow com q 41135212 3072788有一个定义HList 来自HList https hackage haskell org package HList 0 4 1 0 doc
  • 将系统命令的结果绑定到 Haskell 中的变量

    如何在 Haskell 中运行系统命令and将其结果 即标准输出 绑定到变量 在伪 Haskell 中 我正在寻找类似以下内容的内容 import System Process main do output lt callCommand e
  • 导入 Haskell 模块

    我是哈斯克尔的新手 为什么当我尝试使用时Days from Data Time我收到此错误 Could not find module Data Time It is a member of the hidden package time
  • ErrorT 已弃用,但 exceptT 不适合

    我有一个一元计算 在某些时候 由于单子模式匹配 它开始需要 MonadFail 约束 我的简单解决方法是使用以下命令运行它 fmap either error id runErrorT 然而哎呀 Deprecated Use Control
  • 为什么 Parsec 的 sepBy 停止并且不解析所有元素?

    我正在尝试解析一些逗号分隔的字符串 该字符串可能包含也可能不包含具有图像尺寸的字符串 例如 hello world 300x300 good bye world 我写了下面的小程序 import Text Parsec import qua
  • 如何从 haskell 中的 IOError 获取 errno?

    我在 haskell 平台上 GHC 6 12 1 作为 apt get 安装在 Debian Squeeze 上 鉴于我需要在与最初引发它的线程不同的线程上使用它 如何从 IOError 中获取底层 errno 我需要这个的原因是因为我正
  • 什么是欣德利米尔纳?

    我遇到过这个词欣德利 米尔纳 我不确定是否理解它的意思 我已阅读以下帖子 史蒂夫 叶格 动态语言的反击 http steve yegge blogspot com 2008 05 dynamic languages strike back
  • 我应该在 Turtle 或 Foldl 包中使用折叠吗?

    我在使用 Turtle 时遇到了一些困难 直到盯着难以理解的错误消息几分钟后才意识到我使用了错误的fold功能 https hackage haskell org package turtle 1 5 8 docs Turtle Shell
  • Haskell 中的 print 是纯函数吗?

    Is print在 Haskell 中是纯函数 为什么或者为什么不 我认为不是 因为它并不总是返回与纯函数应返回的值相同的值 类型的值IO Int并不是真正的Int 它更像是一张纸 上面写着 嘿 Haskell 运行时 请生成一个Int如此
  • 规范化且不可变的数据模型

    Haskell如何解决 规范化不可变数据结构 问题 例如 让我们考虑一个表示前女友 男友的数据结构 data Man Man name String exes Woman data Woman Woman name String exes
  • Haskell 泛化问题(涉及列表理解)

    假设我想知道a上的所有要点 x y 矩形内的平面has 我可以使用列表推导式来计算 如下所示 let myFun2D x y x lt 0 2 y lt 0 2 现在 如果我想为一个人完成同样的事情 x y z 空间 我可以采取同样的方式并
  • “功能性”Rust 对性能有哪些影响?

    我正在关注 Rust 轨道运动 io https exercism io 我有相当多的 C C 经验 我喜欢 Rust 的 功能 元素 但我担心相对性能 我解决了 行程编码 问题 https exercism io tracks rust
  • 是否可以只迭代一个流一次并执行 2 个或更多操作?

    给定代码 List
  • 如何在 Haskell 中漂亮地打印表格?

    我想在 Haskell 中漂亮地打印一个类似表格的数据结构 列列表 例如 Table StrCol strings a bc c IntCol ints 1 30 2 DblCol doubles 2 0 4 5 3 2 应该渲染类似 st

随机推荐