如何将字符串解析为 Haskell 中的函数?

2024-03-22

我想要一个看起来像这样的函数

readFunc :: String -> (Float -> Float)

它的操作是这样的

>(readFunc "sin") (pi/2)
>1.0

>(readFunc "(+2)") 3.0
>5.0

>(readFunc "(\x -> if x > 5.0 then 5.0 else x)") 2.0
>2.0

>(readFunc "(\x -> if x > 5.0 then 5.0 else x)") 7.0
>5.0

令人难以置信的天真方法(注意这必须用{-# LANGUAGE FlexibleContexts #-})

readFunc :: (Read (Float -> Float)) => String -> (Float -> Float)
readFunc s = read s

gives

No instance for (Read (Float -> Float)) ...

这是有道理的,因为不存在这样的实例。我知道我可以通过编写映射来逐个解析输入字符串String to Float -> Float但我希望能够至少解析 prelude 中最常见的函数,即使这样,工作量也比我想要承担的要多。有一个简单的方法可以做到这一点吗?

只有一种使用提示的解决方案

import Language.Haskell.Interpreter hiding (typeOf)
import Data.Typeable (typeOf)

data Domain = Dom Float Float Float Float Domain
            | SDom Float Float Float Float 
            deriving (Show, Read)

--gets all the points that will appear in the domain
points (SDom a b c d) m = [(x, y)|x <- [a, a+m .. b], y <- [c, c+m .. d]]
points (Dom a b c d next) m = points next m ++ [(x, y)|x <- [a, a+m .. b], y <- [c, c+m .. d]]

readFunc = do
    putStrLn "Enter a domain (as Dom x-min x-max y-min y-max subdomain, or, SDom x-min x-max y-min y-max)"
    domain' <- getLine
    let domain = (read domain') :: Domain
    --
    putStrLn "Enter a mesh size"
    meshSize' <- getLine
    let meshSize = (read meshSize') :: Float 
    --
    putStrLn "Enter an initial value function (as f(x,y))"
    func' <- getLine
    values' <- runInterpreter $ setImports["Prelude"] >>
                                eval ("map (\\(x,y) -> " ++ func' ++ ")" ++ show (points domain meshSize))
    let values = (\(Right v) -> (read v)::([Float])) values'

    --the haskell expression being evaluated
    putStrLn $ ("map (\\(x,y) -> " ++ func' ++ ")" ++ show (points domain meshSize)) 

    --prints the actual values
    putStrLn $ show values 

    --the type is indeed [float]
    putStrLn $ show $ typeOf values 

您可以使用hint http://hackage.haskell.org/package/hint包,或plugins http://hackage.haskell.org/package/plugins。我将向您展示前者(部分原因是我的 Windows 安装显然有点损坏,因为 cabal 不同意我安装了 C 的信念,因此 cabal 安装插件失败)。

字符串 -> 函数很简单:

import Language.Haskell.Interpreter

getF :: String -> IO (Either InterpreterError (Float -> Float))
getF xs = runInterpreter $ do
   setImports ["Prelude"]
   interpret xs (as :: Float -> Float)

您可能想要将其他模块添加到导入列表中。测试结果为

ghci> getF "sin" >>= \(Right f) -> print $ f (3.1415927/2)
1.0
ghci> getF "(\\x -> if x > 5.0 then 5.0 else x)" >>= \(Right f) -> print $ f 7
5.0

(注意转义字符的转义\.)

错误信息

您可能已经注意到,结果包装在 Either 数据类型中。Right f是正确的输出,而Left err给出一个InterpreterError消息,这非常有帮助:

ghci> getF "sinhh" >>= \(Left err) -> print err
WontCompile [GhcError {errMsg = "Not in scope: `sinhh'\nPerhaps you meant `sinh' (imported from Prelude)"}]

示例玩具程序

当然,你可以使用either用你的代码来处理这个问题。让我们举一个假例子respond。你真正的将包含你的程序的所有数学知识。

respond :: (Float -> Float) -> IO ()
respond f = do
   -- insert cunning numerical method instead of
   let result = f 5
   print result

然后,您的程序的一个简单的、一次性的、无用的版本可能是

main = 
   putStrLn "Enter your function please:"
   >> getLine 
   >>= getF 
   >>= either print respond 

会话示例

ghci> main
Enter your function please:
\x -> x^2 + 4
29.0
ghci> main
Enter your function please:
ln
WontCompile [GhcError {errMsg = "Not in scope: `ln'"}]

它为您进行类型检查:

ghci> main
Enter your function please:
(:"yo")
WontCompile [GhcError {errMsg = "Couldn't match expected type `GHC.Types.Float'\n            with actual type `GHC.Types.Char'"}]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将字符串解析为 Haskell 中的函数? 的相关文章

  • Haskell Cabal 包 - 找不到 Paths_ 模块

    我正在开发一个 Haskell 项目 Happstack 服务器 Blaze HTML 前端作为主要库 我想添加一个静态数据目录 看起来你可以使用 Cabal 使用自动生成的Path
  • 在 Haskell 中计算移动平均线

    我正在学习 Haskell 所以我尝试实现移动平均函数 这是我的代码 mAverage Int gt Int gt Float mAverage x a fromIntegral k fromIntegral x k lt rawAvera
  • 在 Haskell 中增长数组

    我想在 Haskell 中实现以下 命令式 算法 给定一个序列对 e0 s0 e1 s1 e2 s2 en sn 其中 e 和 s 部分不一定是自然数不同的是 在每个时间步都会随机选择该序列的一个元素 例如 ei si 并根据 ei si
  • 这个记忆的斐波那契函数是如何工作的?

    在我正在做的函数式编程课程的当前练习作业中 我们必须制作给定函数的记忆版本 为了解释记忆化 给出以下示例 fiblist fibm x x lt 0 fibm 0 0 fibm 1 1 fibm n fiblist n 1 fiblist
  • 为什么 Haskell 的默认字符串实现是一个字符链接列表?

    Haskell 默认值的事实String众所周知 实现在速度和内存方面都效率不高 据我所知 lists一般来说 在 Haskell 中实现为单链表 并且适用于大多数小型 简单数据类型 例如Int 这似乎不是一个好主意 但是对于String这
  • 纯函数怎么能做IO呢?

    我最近了解到莫纳德随机数 http hackage haskell org package MonadRandom 0 1 13 docs Control Monad Random Class html t 3aMonadRandom图书馆
  • Haskell - 用防护罩替换外壳

    我想知道在这部分代码中是否可以用守卫替换 case 语句 firstFunction String gt Maybe MyType secondFunction MyType gt Integer myFunction String gt
  • 如何在 Haskell 中安装库?

    我尝试使用控制 Monad Extra andM https hackage haskell org package extra 1 7 10 docs Control Monad Extra html import Control Mon
  • Haskell 泛化问题(涉及列表理解)

    假设我想知道a上的所有要点 x y 矩形内的平面has 我可以使用列表推导式来计算 如下所示 let myFun2D x y x lt 0 2 y lt 0 2 现在 如果我想为一个人完成同样的事情 x y z 空间 我可以采取同样的方式并
  • 在 Yesod 生态系统中,对某些文本进行 urlencode 的最佳方式是什么?

    我想对一些文本进行 url 编码 例如 用 20 替换每个空格等 我找到了 HTTP Network HTTP Base urlEncode 并且可以使用它 但我想知道是否还有其他通常在 Yesod 生态系统中使用的东西 不幸的是 由于 U
  • 标准的能力

    我发现了一些使用标准的旧例子here http www serpentine com blog 2009 09 29 criterion a new benchmarking library for haskell 看起来好像早在 2009
  • 简单 Haskell Monad - 随机数

    我正在尝试扩展代码这个帖子 https stackoverflow com questions 3944170 haskell and state 接受的答案 允许我能够基于以种子作为参数的函数 randomGen 调用 randomGen
  • Haskell:Data.Numbers.Primes 库在哪里?

    我尝试导入 Data Numbers Primes import Data Numbers Primes 伦哈斯克尔给了我 5 hs 1 8 Could not find module Data Numbers Primes Use v t
  • 有没有更好的方法将 UTC 时间转换为大纪元时间?

    我想将文件的修改时间设置为从 exif 数据获取的时间 为了从 exif 获取时间 我发现 Graphics Exif getTag Exif gt String gt IO Maybe String 要设置文件修改时间 我发现 Syste
  • 如何在haskell中获取变量名称

    我来到 haskell 时有一些 c 背景知识 想知道是否有类似的 define print a printf s d n a a int a 5 print a 应该打印 a 5 这是 augustss 提到的 TH 解决方案 LANGU
  • Haskell:IORef 的性能

    我一直在尝试在 Haskell 中编码一个需要使用大量可变引用的算法 但与纯粹的惰性代码相比 它 也许并不奇怪 非常慢 考虑一个非常简单的例子 module Main where import Data IORef import Contr
  • 这个对自身单位的列表理解是如何工作的?

    在 haskell IRC 频道中有人问 是否有一种简洁的方法来定义一个列表 其中第 n 个条目是之前所有条目的平方和 我认为这听起来像一个有趣的谜题 递归定义无限列表是我真正需要练习的事情之一 所以我启动了 GHCi 并开始尝试递归定义
  • 我该如何实现这个折叠功能呢?

    给出了两种数据类型 颜色 和 植物 data Color Red Pink White Blue Purple Green Yellow deriving Show Eq data Plant Leaf Blossom Color Stal
  • 不同编程语言中的浮点数学

    我知道浮点数学充其量可能是丑陋的 但我想知道是否有人可以解释以下怪癖 在大多数编程语言中 我测试了 0 4 到 0 2 的加法会产生轻微的错误 而 0 4 0 1 0 1 则不会产生错误 两者计算不平等的原因是什么 在各自的编程语言中可以采
  • Haskell:不在范围内:数据构造函数

    今天开始在学校学习 haskell 我遇到了函数问题 我不明白为什么它不在范围内 代码如下 ff Char gt Char gt Char ff A B x 0 y 1 x lt A y lt B x 1 y 0 和错误 md31 hs 2

随机推荐

  • Linkedin API - 按关键字搜索帖子

    我尝试通过 Linkedin API for PHP 将我的 Web 应用程序与 Linkedin 连接 有什么方法可以使用这个通过关键字搜索人们的出版物吗 如果可以的话 我还没有找到方法 我认为他们没有这种本机 所以他们可以避免报废 您可
  • 使用 Angular、node.js 和身份提供商进行 SAML 身份验证

    我想使用 SAML2 实现 SSO 但我不知道如何让它与分布式系统一起工作 其中每个实例都在自己的服务器上独立运行 该环境由三个实例组成 实例 1 有角度的前端 实例 2 node js 后端 使用express js Passport 实
  • Rails:如何安装 keywords.js?

    我想在我的应用程序上实现此功能 但我不知道如何安装它 您能否发布一步一步的信息 以便我了解要放置哪些文件 因为我尝试按照 github 页面上的说明进行操作 但没有成功 http vincentgarreau com articles js
  • 调用 Task.Result 时出现 ThreadAbortException

    我有以下代码 我尝试使用以下命令向远程端点发出请求HttpClient using var client new HttpClient client BaseAddress serviceBaseAddress Task
  • WCF - 网络成本

    我在 IIS 上部署了一个 wcf 服务 使用 basicHttpBinding 和 aspNetCompatibilityEnabled true 我还有一个测试客户端 它同时调用多个服务功能 为了检查客户端和服务器上服务调用的性能 我计
  • Angular 如何使用 rxjs 管道过滤可观察的数据

    我在服务文件中调用了一个名为 getWorkOrders 的方法 该方法又调用服务器来获取记录 这是我的服务 我正在使用新的 HttpClient export class BackendServices private BASE URL
  • 如何自定义 json 格式的 TestNG 报告结果

    我正在使用 TestNG 和 selenium webdriver java 我想制作一个json格式的输出报告 testng可以制作一个json格式的报告吗 请给我一个关于这个问题的例子 您可以编写自己的报告程序 以您需要的任何格式生成测
  • Python 编程。访问 Windows 右键菜单选项

    我希望能够自动化工作中的一些任务 其中之一是将 Power Point 文件合并并转换为 PDF 我是个新手 我刚刚读完 Magus Heitland 的 Beginning Python 所以我不太确定我具体要问什么 在 Windows
  • 编码的 UI 测试生成器无法为记录的操作生成代码

    我尝试在 Visual Studio 2015 Enterprise 中记录 Windows 10 上运行的 IE 中最简单的编码 UI 操作 问题是最近我开始得到Value cannot be null Parameter name ke
  • 在 ruby​​ 进程之间处理大数据对象

    如果使用 Marshal dump 写入文件 我的 Ruby 哈希值将达到大约 10 MB gzip 压缩后大约为 500 KB 在 ruby 中迭代和更改这个哈希值非常快 不到一毫秒 即使复制它也非常快 问题是我需要在 Ruby on R
  • C# 序列化对象并获取字节流

    我有一个对象 一个实例Serializable班级 我想知道如何以字节流的形式获取这个对象 我知道我可以使用BinaryFormatter http msdn microsoft com en us library c5sbs8z9 asp
  • 提高 pandas groupby 的性能

    我有一个用 Python 编写的机器学习应用程序 其中包括数据处理步骤 当我编写它时 我最初在 Pandas DataFrames 上进行数据处理 但是当这导致性能糟糕时 我最终使用普通 Python 重写了它 用 for 循环代替矢量化操
  • 获取错误的毫秒延迟值

    我试图获得 1 毫秒的延迟 但延迟增加了 15 倍 我也尝试过使用 WindowsSleep 1 函数也给了我相同的结果 为什么我没有得到精确的毫秒延迟 它的工作延迟为 1 秒 include
  • 表行的 jQuery 条件选择器

    我有一个表 其中包含数据 td item td td order code td td price td 我正在使用 jQuery 处理该表 它需要查找订单代码 each productList tbody tr function var
  • #pragma 末尾的隐式屏障

    朋友们 我正在尝试学习 openMP 范例 我使用以下代码来理解 omp for pragma int main void int tid int i omp set num threads 5 pragma omp parallel pr
  • SceneKit 在与 Swift 接触后获取纹理坐标

    我想在 3D SceneKit 场景中操作 2D 纹理 因此我使用此代码来获取本地坐标 IBAction func tap sender UITapGestureRecognizer var arr NSArray my3dView hit
  • Javascript - 获取两个日期之间的日期数组

    var range getDates new Date new Date addDays 7 我希望 范围 是一组日期对象 一个代表两个日期之间的每一天 诀窍在于它还应该处理月份和年份的边界 Date prototype addDays f
  • .Net core DI 范围验证,范围与瞬态?

    正在阅读docs https learn microsoft com en us aspnet core fundamentals dependency injection view aspnetcore 2 2 scope validat
  • Mongoose 中的“__v”字段是什么

    我在用着Mongoose版本 3 与MongoDB2 2 版 我注意到一个 v字段已开始出现在我的MongoDB文件 这与版本控制有关吗 它是如何使用的 From here http mongoosejs com docs guide ht
  • 如何将字符串解析为 Haskell 中的函数?

    我想要一个看起来像这样的函数 readFunc String gt Float gt Float 它的操作是这样的 gt readFunc sin pi 2 gt 1 0 gt readFunc 2 3 0 gt 5 0 gt readFu