到目前为止,我的尝试是:
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的评论中写的那样,它可能与存在主义类型有关,但我偶然发现了一个奇怪的行为:
编译:
{-# 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'是刚性类型变量消息)
{-# 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)=>吨。我能定义一些东西(typeconstructor,consts dunno)吗?
答案 0 :(得分:5)
当我取消注释test
的定义并尝试编译代码时,我得到“模糊的类型变量”。严格要求。要理解这个含糊不清的原因,请考虑一下:
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:
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)
要求所有Footables都是Show and Read的实例,只需执行以下操作:
class (Show a, Read a) => Footable a where
foo2 :: a
就像你在评论中所做的那样,但没有在foo2的签名中再次指定约束。
答案 1 :(得分:2)
正如sepp2k所说,Ghc无法猜测foo2的返回类型。约束它(这是你的问题的标题)添加内联类型签名。
test = print(foo2 :: FooT)