【发布时间】:2018-04-03 23:13:48
【问题描述】:
我正在尝试编写一些 EDSL 来为键分配值。所以我有以下数据类型的值:
data Value = B Bool | I Int
我希望有统一的方式将不同的值转换为Value 类型的对象。所以我创建了以下类型类:
class ToValue a where toValue :: a -> Value
instance ToValue Bool where toValue = B
instance ToValue Int where toValue = I
很遗憾,这段代码无法编译:
foo :: [Value]
foo = [toValue True, toValue 3]
我明白原因。但这让我很难过。我真的不明白如何解决这个问题......如果我启用了-XOverloadedStrings 并且我想将T Text 构造函数添加到我的Value 类型,事情会变得更加困难。
我的最终目标是有能力写出这样的东西:
foo :: [(Text, Value)]
foo = [ "key1" !!! True
, "key2" !!! 42
, "key3" !!! "foo"
, "key4" !!! [5, 7, 10]
]
我知道我总是可以手动将每个值包装到相应的构造函数中,但我宁愿避免这种情况(因为在我的现实生活中构造函数比一个字母长,并且代码并没有真正减少构造函数的噪音)。
我可以做些什么来实现最接近的实现?如果可能的话,我想避免Value 的不安全Num 实例...
【问题讨论】:
-
原来
ExtendedDefaultRules工作。出于某种原因,我认为这是 GHCi 独有的东西。
标签: haskell polymorphism overloading typeclass