gpt4 book ai didi

haskell - 为什么haskell不能推导出这个多参数类型类?

转载 作者:行者123 更新时间:2023-12-02 12:10:47 34 4
gpt4 key购买 nike

我有两个类型类

class Concatable a where
empty :: a
(<+>) :: a -> a -> a

class Concatable b => Output a b where
out :: a -> b

以及以下函数

nl :: (Output a AnsiDark) => [a] -> AnsiDark
nl a = foldr addNl empty a
where
addNl :: a -> AnsiDark -> AnsiDark
addNl ast org = doAddIf ast <+> org
doAddIf :: a -> AnsiDark
doAddIf ast = if out ast == sDedent
then out ast
else out ast <+> sNewline

(AnsiDark 实现 ConcatablesDedentAnsiDark 类型的常量)

以及启用以下语言扩展(这甚至可能与问题无关,我对这些复杂类型相关的问题相当陌生)

{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}

我收到以下错误:

../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

我不太明白为什么 haskell 无法推导 a...我会像这样使用带有 out 的类型注释

out @a @AnsiDark

但是类型注释似乎不适用于类型变量。那么...我的问题到底是什么?我该如何解决这个问题?

最佳答案

nl :: (Output a AnsiDark) => [a] -> AnsiDark
...
where
doAddIf :: a -> AnsiDark
...

这两行中出现的a不相同。就好像你写了:

nl :: (Output x AnsiDark) => [x] -> AnsiDark
...
where
doAddIf :: y -> AnsiDark
...

由于您在 doAddif 中使用 out,因此您需要将 Output 约束添加到其签名中(我相信如果您删除它就会起作用)签名,因为将推断出正确的签名)。

您可能还对 ScopedTypeVariables 扩展感兴趣。启用此功能后,如果您编写

nl :: forall a. (Output a AnsiDark) => [a] -> AnsiDark

那么您可以在 where 子句中的签名以及 out @ 等类型应用程序中引用 that a您尝试过的@AnsiDark

关于haskell - 为什么haskell不能推导出这个多参数类型类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55770849/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com