首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将返回类型约束为上下文

将返回类型约束为上下文
EN

Stack Overflow用户
提问于 2010-07-03 10:24:23
回答 2查看 216关注 0票数 4

到目前为止,我的尝试如下:

代码语言:javascript
复制
module Main where

data FooT = One | Two deriving (Show, Read)
{-
That is what I want
foo :: (Show a, Read a) => a
foo = One
-}

--class Footable (Show a, Read a) => a where
class Footable a where
  --foo2 :: (Show a, Read a) => a
  foo2 :: a

instance Footable FooT where
  foo2 = One

-- test = print foo2

我要测试编译。我不认为这个问题是围绕着普遍量化的。ghc说,a是一个“严格类型变量”,编辑(刚性类型变量),但我并不真正理解这是什么。这个问题似乎与this有关

编辑

正如我在评论@sepp2k中所写的,这可能是关于存在主义类型的,但我被一种奇怪的行为绊倒了:

这确实汇编了:

代码语言:javascript
复制
{-# LANGUAGE OverlappingInstances, FlexibleInstances, OverlappingInstances,
UndecidableInstances, MonomorphismRestriction, PolymorphicComponents #-}
{-# OPTIONS_GHC -fno-monomorphism-restriction #-}

module Main where

    class (Num a) => Numable a where
      foo2 :: a

    instance (Num a) => Numable a where
      foo2 = 1

    instance Numable Int where
      foo2 = 2

    instance Numable Integer where
      foo2 = 3

    --test = foo2 + foo2 -- This does NOT compile (ambiguous a) 
    test = (foo2::Integer) + foo2 --this works

但这不是(“a”是一个刚性类型的变量消息)

代码语言:javascript
复制
{-# LANGUAGE OverlappingInstances, FlexibleInstances, OverlappingInstances,
UndecidableInstances, MonomorphismRestriction, PolymorphicComponents #-}
{-# OPTIONS_GHC -fno-monomorphism-restriction #-}

module Main where

    data FooT = One | Two deriving (Show, Read)
    data BarT = Ten deriving (Show, Read)

    class (Show a, Read a) => Footable a where
      foo2 :: a

    instance (Show a, Read a) => Footable a where
      foo2 = Ten

    instance Footable FooT where
      foo2 = One

    main = print foo2

这是因为1 ::(Num t) => t。我能定义像那样的东西(类型结构体,typeconstructor)吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-07-03 10:38:01

当我取消对test定义的注释并试图编译您的代码时,我会得到“模棱两可的类型变量”。没有严格的规定。要理解为什么这是模棱两可的,请考虑如下:

代码语言:javascript
复制
module Main where

data FooT = One | Two deriving (Show, Read)
data BarT = Three | Four deriving Show

class Footable a where
  foo2 :: a

instance Footable FooT where
  foo2 = One

instance Footable BarT where
  foo2 = Three

main = print foo2  -- Should this print One or Three?

当然,在您的代码中只有一个Footable实例,所以理论上haskell可以推断您希望使用为foo2定义的FooT,因为这是作用域中唯一的实例。但是,如果它这样做了,一旦您导入一个恰好定义了Footable的另一个实例的模块,代码就会中断,所以haskell不会这样做。

要解决您的问题,需要对foo2进行如下类型的注释:

代码语言:javascript
复制
module Main where

data FooT = One | Two deriving (Show, Read)

class Footable a where
  foo2 :: a

instance Footable FooT where
  foo2 = One

main = print (foo2 :: FooT)

要要求所有的脚注都是Show的实例,只需做:

代码语言:javascript
复制
class (Show a, Read a) => Footable a where
  foo2 :: a

就像您在注释中所做的那样,但是在foo2的签名中没有再次指定约束。

票数 5
EN

Stack Overflow用户

发布于 2010-07-03 11:12:52

正如sepp2k所说,Ghc无法猜测foo2的返回类型。做约束它(这是你的问题的标题)添加一个内联类型的签名。

test = print (foo2 ::FooT)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3171179

复制
相关文章

相似问题

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