Haskell-自定义类型的元组

时间:2018-08-13 18:32:21

标签: haskell

我希望能够代表自定义类型的元组。我介绍的内容如下:

type Name = String

data DataType a  = DataType a deriving Show

data Val a = Single (DataType a) | List [(DataType a)] deriving Show

data State a = State [(Name,(Val a))] deriving Show

append :: (Name, (Val a)) -> State a -> State a
append nv (State st) = State (st ++ [nv])

现在的问题是,状态不能为[(“ NUM1”,单(DataType 1)),(“ STR1”,单(DataType“ Hello”))]。我希望能够执行以下操作:

*Main> num1 = Single (DataType 1)
*Main> num1
Single (DataType 1)
*Main> str1 = Single (DataType "str1")
*Main> str1
Single (DataType "str1")
*Main> st1 = append ("NUM1",num1) (State [])
*Main> st1
State [("NUM1",Single (DataType 1))]
*Main> st2 = append ("STR1",str1) st1

<interactive>:8:28: error:
    • No instance for (Num [Char]) arising from a use of ‘st1’
    • In the second argument of ‘append’, namely ‘st1’
      In the expression: append ("STR1", str1) st1
      In an equation for ‘st2’: st2 = append ("STR1", str1) st1

当我尝试添加(Name, Val String)时,Haskell抱怨,因为它已经将State解释为State [(Name, (Val Int)],这并不是我的意图。

如何实现State作为DataType Int或DataType String的字典?

PS: 这种功能的一种可能用法是在生成的代码中,其中将不止一种类型的代码生成为代码,并且它还使用上面的功能来表示状态。 例如,用户可以使用UI定义某些类型,然后系统会为这些类型以及上面定义的state生成Haskell代码。

1 个答案:

答案 0 :(得分:4)

Haskell并不真正支持混合类型列表,但是https://stackoverflow.com/a/7787429/3953988有一些好的解决方案。

根据该答案,或者:

  • 创建一个总和为新的容器类型(例如:data DataType = X Int | Y String...
  • 使用存在性类型(例如:data DataType = forall a. Show a => Datatype a)(显示为可选约束,鉴于您希望DataType可显示,我认为您希望这样做)