首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么这个类型变量是不明确的?

为什么这个类型变量是不明确的?
EN

Stack Overflow用户
提问于 2009-04-03 08:16:57
回答 3查看 1.3K关注 0票数 6

Cabbage.hs:

代码语言:javascript
复制
module Cabbage where 
class Cabbage a
  where foo :: a -> String      -- the parameter is only present for its type,
                                -- the parameter value will be ignored
        bar :: String -> a
quux :: Cabbage a => String -> a
quux s = bar (s ++ foo (undefined :: a))

当我编译(使用ghc)时,我得到这个错误消息:

代码语言:javascript
复制
Cabbage.hs:7:19:
    Ambiguous type variable `a' in the constraint:
      `Cabbage a' arising from a use of `foo' at Cabbage.hs:7:19-38
    Probable fix: add a type signature that fixes these type variable(s)

我不明白为什么a是模棱两可的。难道第7行的a和第6行的a是相同的吗?我该如何解决这个问题?

或者,有没有更好的方法来声明每个实例的常量?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-04-03 10:51:34

使用限定作用域的类型变量,您可以让GHC知道undefined :: a应该是相同的(否则a只是forall a. a的简写)。然后,作用域类型变量必须显式地进行forall限定:

代码语言:javascript
复制
{-# LANGUAGE ScopedTypeVariables #-}
module Cabbage where 
class Cabbage a
  where foo :: a -> String      -- the parameter is only present for its type,
                                -- the parameter value will be ignored
        bar :: String -> a
quux :: forall a. Cabbage a => String -> a
quux s = bar (s ++ foo (undefined :: a))
票数 11
EN

Stack Overflow用户

发布于 2009-04-03 10:25:16

问题是Haskell不知道foo对应的是哪个Cabbage实例。据我所知,它与(undefined :: a)中的aquux :: Cabbage a => String -> a中的a不匹配

假设这就是你想要的,你可以这样做:

代码语言:javascript
复制
quux :: Cabbage a => String -> a
quux s = result
    where result = bar (s ++ foo result)

这将foo和bar绑定在一起,因此它对两者使用相同的实例,并且由于您实际上不需要foo的输入值,因此它将触底。不过,我不知道有什么更好的方法来处理每个实例的常量。希望其他人也能这样做。

票数 2
EN

Stack Overflow用户

发布于 2009-04-04 01:43:08

您可以将多态部分作为函数提取出来

代码语言:javascript
复制
quux :: Cabbage a => String -> a
quux s = quux' undefined
    where quux' :: Cabbage a => a -> a
          quux' x = bar (s ++ foo x)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/713003

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档