简体   繁体   English

将返回类型约束到上下文

[英]Constraining the return type to a Context

Here are my attempts so far: 到目前为止,这是我的尝试:

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

I want test to compile. 我想测试编译。 I don't think the problem revolves around universal quantification. 我认为问题不在于普遍量化。 ghc says that a is a 'strict type-variable' edit ( rigid type variable) but I don't really comprehend what this is. ghc说a是“严格类型变量” 编辑刚性类型变量),但我并不真正理解这是什么。 The question seems to be related to this 这个问题似乎与有关

Edit 编辑

As I wrote in my comment @sepp2k it's probably about the existential type but I have stumbled over a curious behaviour: 正如我在@ sepp2k的评论中所写的那样,它可能与存在类型有关,但是我偶然发现了一种奇怪的行为:

This does compile: 这样可以编译:

{-# 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

but this does not (`a' is a rigid type variable message) 但这不是(“ a”是固定类型的变量消息)

{-# 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

that's so because 1 :: (Num t) => t. 之所以这样是因为1 ::(Num t)=> t。 Can I define something (typeconstructor, consts dunno) like that? 我可以定义类似的东西(typeconstructor,consts dunno)吗?

When I uncomment the definition of test and try to compile your code, I get "ambiguous type variable". 当我取消test的定义的注释并尝试编译您的代码时,我得到“模糊类型变量”。 Nothing about strictness. 没关系。 To understand why this is ambiguous consider this: 要了解为什么这是模棱两可的,请考虑以下几点:

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?

Of course in your code there is only one instance of Footable, so haskell could in theory infer that you want to use the foo2 defined for FooT because that's the only instance in scope. 当然,在您的代码中只有Footable的一个实例,因此haskell从理论上可以推断出您想使用为FooT定义的foo2 ,因为这是作用域中的唯一实例。 However if it did that, the code would break as soon as you import a module that happens to define another instance of Footable, so haskell doesn't do that. 但是,如果这样做,则在导入恰好定义了Footable的另一个实例的模块时,代码将立即中断,因此haskell不会这样做。

To fix your problem you need to annotate foo2 with its type like so: 要解决您的问题,您需要使用以下类型注释foo2:

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)

To require that all Footables be instances of Show and Read simply do: 要要求所有Footables都是Show和Read的实例,只需执行以下操作:

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

Like you did in your comments, but without specifying the constraint again in the signature of foo2. 就像您在注释中所做的一样,但是没有在foo2的签名中再次指定约束。

As sepp2k said, Ghc can't guess the return type of foo2. 正如sepp2k所说,Ghc无法猜测foo2的返回类型。 Do constraint it (which is the title of your question) add an inline type signature. 要约束它(这是您的问题的标题),请添加内联类型签名。

test = print (foo2 :: FooT) 测试=打印(foo2 :: FooT)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM