Haskell添加推断类型报错:如何正确声明函数类型?
问题分析与解决
错误原因
你写的(hqFace :: rel)里的rel和顶层类型签名的rel不是同一个变量——Haskell默认情况下,表达式内的类型签名会创建全新的类型变量(报错里的rel1就是这个新变量),而顶层签名的MorphsHQ rel约束只作用于顶层的rel,编译器无法推断新的rel1满足MorphsHQ约束,所以报错。
解决方法
方法1:移除表达式内的类型标注(推荐)
顶层的类型签名已经明确了rel的约束,只要hqFace本身是多态类型(比如hqFace :: MorphsHQ a => a),编译器会自动推断它的类型为rel,不需要额外标注:
coords2faces :: (MorphsHQ rel, Eq rel, Eq obj, Ord obj) => State (Store obj rel) [(obj, obj)] coords2faces = do f <- rel3 hqFace return f
方法2:开启ScopedTypeVariables扩展绑定类型变量
如果一定要保留表达式内的类型标注,需要开启ScopedTypeVariables扩展,让表达式内的rel引用顶层签名里的同名变量:
- 在文件顶部添加扩展声明:
{-# LANGUAGE ScopedTypeVariables #-}
- 顶层签名用
forall显式声明类型变量,确保作用域覆盖表达式:
coords2faces :: forall rel obj. (MorphsHQ rel, Eq rel, Eq obj, Ord obj) => State (Store obj rel) [(obj, obj)] coords2faces = do f <- rel3 (hqFace :: rel) return f
内容的提问来源于stack exchange,提问作者user855443
相关产品推荐
相关产品推荐

