在Haskell中实现函数

jdzmm42g  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(193)

我正在尝试使用我自己的类型别名和数据构造函数实现一个eval函数。这个函数应该返回一个更新的字典Dict和程序计数器Counter,根据输入的Func。基本上,我希望它在输入正确的情况下递增计数器。下面是我的类型别名:

type Counter = Int
type Name = String
type Dict = Map Name Const

这是我创建的一个类型,用于后面我在下面提到的类中:

data Func = GET_INT Int
          | GET_DICT Name
          | JUMP Counter
          deriving Show

这是一个包含函数的类,我把Func作为它的示例:

class Evaluate a where
  eval ::  Func -> (Dict, Counter) -> Maybe (Dict, Counter)
 
instance Evaluate Func where
  eval (GET_INT a)(d, c) = Just(d, c+1)
  eval (GET_DICT a)(d, c) = Just(d, c+1)
  eval (JUMP a)(d, c) = Just(d, c+1)
  eval = Nothing

然而,我得到了一些错误。首先,我得到了以下内容:应为类型,但“Counter”具有种类“Const”
其次,我不确定我输入的Evaluate类的参数是否正确,因为a没有在任何地方使用。另外,我认为函数的输入不会像上面那样工作。
有人能帮我弄清楚如何让这个函数工作吗?

qacovj5a

qacovj5a1#

我喜欢的类型有:

type Counter = Int
type Name = String
type Dict = Map Name Int

这些都是类型别名,但没关系。
这是我的数据类:

data Func = GET_INT Int
          | GET_DICT Name
          deriving Show

术语“dataclass”没有任何意义。Func是一个类型。有两个数据构造函数。好的。
这是我要创建的函数的类:

class Evaluate a where
  eval ::  a -> (Dict, Counter) -> Maybe (Dict, Counter)

这没有多大意义。什么是eval,为什么要用a来参数化它?我认为最好先定义eval :: Func -> (Dict, Counter) -> Maybe (Dict, Counter),然后仔细考虑为什么要使它更具多态性。

eval (GET_INT a)([(d1, d2)],c) = ([(d1,d2)], c)
eval (GET_DICT a)([(d1, d2)],c) = ([(d1,d2)], c)

这是我得到的错误:'eval'的方程式有不同数目的参数。
不。您提供的代码不是错误。您应该始终提供用于产生导致您混淆的错误的实际代码。
第一个实际错误:

so.hs:15:20: error:
    • Couldn't match type ‘[(a0, b0)]’ with ‘Map Name Int’
      Expected type: Dict
        Actual type: [(a0, b0)]
    • In the pattern: [(d1, d2)]
      In the pattern: ([(d1, d2)], c)
      In an equation for ‘eval’:
          eval (GET_INT a) ([(d1, d2)], c) = ([(d1, d2)], c)
   |
15 |   eval (GET_INT a)([(d1, d2)],c) = ([(d1,d2)], c)

这是因为,除了一个小的例外,语法[ ... ]是一个列表,而不是一个Map。你不能在Map上进行模式匹配,而应该只匹配一个变量,比如env

so.hs:15:36: error:
    • Couldn't match expected type ‘Maybe (Dict, Counter)’
                  with actual type ‘([(a0, b0)], Counter)’
    • In the expression: ([(d1, d2)], c)
      In an equation for ‘eval’:
          eval (GET_INT a) ([(d1, d2)], c) = ([(d1, d2)], c)
      In the instance declaration for ‘Evaluate Func’
    • Relevant bindings include
        d2 :: b0 (bound at so.hs:15:26)
        d1 :: a0 (bound at so.hs:15:22)
   |
15 |   eval (GET_INT a)([(d1, d2)],c) = ([(d1,d2)], c)

(a,b)的元组与Maybe (a,b)不一样。遗憾的是,你显然已经知道这一点,但粘贴了分散注意力的代码-在问这个问题之前清理代码。
如果我们解决了这两个问题,那么我们得到的代码加载良好,但完全没有价值:

import Data.Map

type Counter = Int
type Name = String
type Dict = Map Name Int

data Func = GET_INT Int
          | GET_DICT Name
          deriving Show

class Evaluate a where
  eval ::  a -> (Dict, Counter) -> Maybe (Dict, Counter)
 
instance Evaluate Func where
  eval (GET_INT a) (env,c) = Just (env, c)
  eval (GET_DICT a) (env,c) = Just (env, c)

相关问题