gpt4 book ai didi

function - Haskell 中的抽象函数

转载 作者:行者123 更新时间:2023-12-02 21:35:14 25 4
gpt4 key购买 nike

我目前正在上 Haskell 类(class),但在理解函数如何作为参数传递时遇到了一些困难。对于这项作业,我们的任务是创建一个计算表达式的程序。为了减少重复,我想通过创建一个辅助函数来抽象该函数,该函数将运算符作为输入并返回结果

主要功能:

eval :: EDict -> Expr -> Maybe Double
eval _ (Val x) = Just x
eval d (Var i) = find d i
eval d (Add x y) = evalOp d (+) x y
eval d (Mul x y) = evalOp d (*) x y
eval d (Sub x y) = evalOp d (-) x y

辅助函数:

evalOp:: EDict -> ((Num a) => a -> a -> a) -> Expr -> Expr -> Maybe Double
evalOp d op x y =
let r = eval d x
s = eval d y
in case (r, s) of
(Just m, Just n) -> Just (m `op` n)
_ -> Nothing

其他定义

data Expr
= Val Double
| Add Expr Expr
| Mul Expr Expr
| Sub Expr Expr
| Dvd Expr Expr
| Var Id
| Def Id Expr Expr
deriving (Eq, Show)

type Dict k d = [(k,d)]

define :: Dict k d -> k -> d -> Dict k d
define d s v = (s,v):d

find :: Eq k => Dict k d -> k -> Maybe d
find [] _ = Nothing
find ( (s,v) : ds ) name | name == s = Just v
| otherwise = find ds name

type EDict = Dict String Double

我研究了如何将 +、- 和 * 传递给其他函数,发现这些运算符是由以下定义定义的:

ghci> :t (*)
(*) :: (Num a) => a -> a -> a

但是,当我运行代码时,出现以下编译错误:

Illegal polymorphic or qualified type: Num a => a -> a -> a
Perhaps you intended to use RankNTypes or Rank2Types
In the type signature for ‘evalOp’:
evalOp :: EDict
-> ((Num a) => a -> a -> a) -> Expr -> Expr -> Maybe Double

我不太确定为什么会发生这种情况,因为我给了我的函数由 Haskell 定义的正确参数。任何帮助将不胜感激,因为我对这门语言还很陌生。

最佳答案

现在,您的 Expr 数据类型仅限于 Double 值表达式,因此无需处理多态性。

evalOp:: EDict -> (Double -> Double -> Double) -> Expr -> Expr -> Maybe Double
evalOp d op x y =
let r = eval d x
s = eval d y
in case (r, s) of
(Just m, Just n) -> Just (m `op` n)
_ -> Nothing

(+)::Num a => a -> a -> aevalOp 的有效参数,因为它的类型可以“限制”为 双 -> 双 -> 双.

> let f :: Double -> Double -> Double; f = (+)
> f 3 5
8.0
<小时/>

如果您的表达式类型被参数化,那么您将在您的函数上放置一个 Num a 约束(而不仅仅是涉及 a 的参数>,因为您希望在整个函数中使用相同的 a)。

data Expr a
= Val a
| Add (Expr a) (Expr a)
| Mul (Expr a) (Expr a)
| Sub (Expr a) (Expr a)
| Dvd (Expr a) (Expr a)
| Var Id
| Def Id (Expr a) (Expr a)
deriving (Eq, Show)

type EDict a = Dict String a

evalOp:: Num a => EDict a -> (a -> a -> a) -> Expr a -> Expr a -> Maybe a
evalOp d op x y =
let r = eval d x
s = eval d y
in case (r, s) of
(Just m, Just n) -> Just (m `op` n)
_ -> Nothing


eval :: Num a => EDict a -> Expr a -> Maybe a
eval _ (Val x) = Just x
eval d (Var i) = find d i
eval d (Add x y) = evalOp d (+) x y
eval d (Mul x y) = evalOp d (*) x y
eval d (Sub x y) = evalOp d (-) x y

关于function - Haskell 中的抽象函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58527107/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com