为什么可以';t haskell推导出这个多参数类型的类?
我有两门打字课为什么可以';t haskell推导出这个多参数类型的类?,haskell,Haskell,我有两门打字课 class Concatable a where empty :: a (<+>) :: a -> a -> a class Concatable b => Output a b where out :: a -> b 我得到以下错误: ../src-hs/ANSITerm.hs:65:22: error: • Could not deduce (Output a1 AnsiDark) arising from a us
class Concatable a where
empty :: a
(<+>) :: a -> a -> a
class Concatable b => Output a b where
out :: a -> b
我得到以下错误:
../src-hs/ANSITerm.hs:65:22: error:
• Could not deduce (Output a1 AnsiDark) arising from a use of ‘out’
from the context: Output a AnsiDark
bound by the type signature for:
nl :: forall a. Output a AnsiDark => [a] -> AnsiDark
at ../src-hs/ANSITerm.hs:59:1-44
• In the first argument of ‘(==)’, namely ‘out ast’
In the expression: out ast == sDedent
In the expression:
if out ast == sDedent then out ast else out ast <+> sNewline
但是类型注释似乎不适用于类型变量。所以我到底有什么问题?我该怎么解决呢
nl :: (Output a AnsiDark) => [a] -> AnsiDark
...
where
doAddIf :: a -> AnsiDark
...
这两行上出现的a
s不相同。就好像你写过:
nl :: (Output x AnsiDark) => [x] -> AnsiDark
...
where
doAddIf :: y -> AnsiDark
...
由于您使用的是out
indoAddif
,因此需要将Output
约束添加到其签名中(我相信如果删除签名,它会起作用,因为将推断出正确的签名)
您可能还对ScopedTypeVariables
扩展感兴趣。启用此选项后,如果您编写
nl :: forall a. (Output a AnsiDark) => [a] -> AnsiDark
然后,您可以在
where
子句的签名中以及在您尝试的out@a@AnsiDark
之类的类型应用程序中引用该a
。(输出a1 AnsiDark)
是一个约束。编译器正在尝试将其与输出
的实例相匹配,以便知道如何实现输出
。您似乎根本没有实例。如果您没有给出ast的表达式,您希望它产生什么?从Hugs编译器得到的消息是未解决的重载
。这是更好的解释吗?这不是一个“复杂类型相关问题”。(一般来说,GHC的信息都认为你在尝试做一些非常花哨的事情。在我看来,这些信息中充满了令人眩晕的类型理论。)
nl :: (Output a AnsiDark) => [a] -> AnsiDark
...
where
doAddIf :: a -> AnsiDark
...
nl :: (Output x AnsiDark) => [x] -> AnsiDark
...
where
doAddIf :: y -> AnsiDark
...
nl :: forall a. (Output a AnsiDark) => [a] -> AnsiDark