haskell - 使用存在类型 Haskell 时出现类型错误
问题描述
我正在 Haskell 中对存在类型进行实验。我正在构建一个非常短的 Json 库并尝试构建一个折叠。我在使用forall
量词的代码中出现错误!
class (Show m) => JsonValue m
instance JsonValue Int
instance JsonValue Double
instance JsonValue String
instance JsonValue Bool
data Json = JObject [(String, Json)]
| JArray [Json]
| forall a . (JsonValue a) => JValue a
foldJ :: ([(String, b)] -> b) -> ([b] -> b) -> forall a . (JsonValue a) => (a -> b) -> Json -> b
foldJ object array value (JObject xs) = object $ map (bimap id (foldJ object array value)) xs
foldJ object array value (JArray xs) = array $ map (foldJ object array value) xs
foldJ object array value (JValue x) = value x -- ERROR HERE
我在用-XExistentialTypes -XFlexibleInstances -XRank2Types
错误如下所示:
Json.hs:335:47: error:
• Couldn't match expected type ‘a’ with actual type ‘a1’
‘a1’ is a rigid type variable bound by
a pattern with constructor:
JValue :: forall a. JsonValue a => a -> Json,
in an equation for ‘foldJ’
at Json.hs:335:27-34
‘a’ is a rigid type variable bound by
the type signature for:
foldJ :: ([(String, b)] -> b)
-> ([b] -> b) -> forall a. JsonValue a => (a -> b) -> Json -> b
at Json.hs:(333,1)-(335,47)
• In the first argument of ‘value’, namely ‘x’
In the expression: value x
In an equation for ‘foldJ’:
foldJ object array value (JValue x) = value x
• Relevant bindings include
x :: a1 (bound at Json.hs:335:34)
value :: a -> b (bound at Json.hs:335:20)
|
335 | foldJ object array value (JValue x) = value x
| ^
Failed, one module loaded.
这真的让我很困惑。我用过打字孔,一切看起来都是正确的类型,但是当我把它们放在一起时,没有任何效果
解决方案
与往常一样,签名被解析为右关联,即它是
foldJ :: ([(String, b)] -> b)
-> ( ([b] -> b)
-> ( ∀ a . (JsonValue a)
=> (a -> b) -> (Json -> b)
)
)
并不是说 ∀ 量化了第二次应用的结果。因此它处于协变位置,这意味着使用该函数的人可以选择什么类型a
。事实上你的签名相当于
foldJ :: JsonValue a
=> ([(String, b)] -> b) -> ([b] -> b) -> (a -> b) -> (Json -> b)
但这不是你想要表达的:调用者无法选择类型,因为它隐藏在 json 结构中!
您真正想要的是让 quantor 只运行在a -> b
参数上,即调用者必须提供适用于任何类型 a
的参数。
foldJ :: ([(String, b)] -> b)
-> ( ([b] -> b)
-> ( (∀ a . (JsonValue a) => (a -> b))
-> (Json -> b)
)
)
推荐阅读
- c# - 更新动态数据网格时出现 WPF 绑定错误
- python - 带有拆分字符串的 dataframe.loc
- bash - 如何触摸具有不同名称和不同创建日期的文件
- amazon-web-services - 确保来自 SQS 的消息在给定时间被单个消费者消费
- python-3.x - “列中没有['Horsepower']”错误来了?
- mysql - logstash 配置中的 JDBC 插件问题
- ios - 如何将注解的标题和描述数据传递给另一个 ViewController
- spring-cloud-dataflow - 如何将带有空格的字符串属性传递给 Spring Cloud Data Flow 任务?
- c# - 二维数组中的蛇
- modelica - 受控泵组件 - 初始化错误 - Modelica