![](/img/trans.png)
[英]Why isn't GeneralizedNewtypeDeriving a Safe Haskell?
[英]Haskell - GeneralizedNewtypeDeriving pragma's interaction with constraints and datatypes
这是我的代码引起的问题:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
class NewConstraint a where
getTrue :: a -> Bool
newtype Identity a = Identity a
deriving (Eq, Show, Num)
instance (Num a, NewConstraint a) =>
NewConstraint (Identity a) where
getTrue x = True
test :: Bool
test = getTrue (Identity 1)
我对GeneralizedNewtypeDeriving
pragma 的使用是否正确? 我原本打算让Identity a
Num a
特征,而无需为NewConstraint
设置Num a
约束实例,但它没有用。 这种方法可行吗? 我哪里做错了?
2021 年 6 月 30 日更新
这是我当前的代码:
class NewConstraint a where
getTrue :: a -> a
newtype Identity a = Identity a
deriving (Show)
instance NewConstraint (Identity a) where
getTrue x = x
-- test :: Identity Integer
test = getTrue (Identity 1)
它无需{-# LANGUAGE GeneralizedNewtypeDeriving #-}
。 什么时候需要编译指示?
通过GeneralizedNewtypeDeriving
for Identity
派生的Num
实例具有以下形式:
instance (Num a) => Num (Identity a) where
fromInteger i = Identity (fromInteger i)
Identity x + Identity y = Identity (x + y)
-- …
-- Similar for ‘(-)’, ‘(*)’, ‘abs’, ‘negate’, ‘signum’.
-- …
也就是说,如果包装类型X
在Num
,那么你可以写1 :: X
,那么Identity X
也在Num
,所以你也可以写1 :: Identity X
; 同样,您可以使用Num
算术运算符:
x, y, z :: Identity Int
x = Identity 5
y = Identity 7
z = x * y -- == Identity 35
因此,您可以只写Identity 1
,而不是通过默认Num a => a
到Integer
来编写具有Identity Integer
类型的Identity Integer
1
。 例如,如果您从NewConstraint (Identity a)
实例中删除不明确的Num a
& NewConstraint a
约束,那么您可以编写:
test :: Bool
test = getTrue (1 :: Identity Int)
或者,使用PartialTypeSignatures
语言选项,您可以省略内部注释,它将包装类型默认为Integer
:
test = getTrue (1 :: Identity _)
在这种特殊情况下,您需要一些注释,原因与在show (read "123")
需要注释show (read "123")
原因相同:您需要确定read :: Read a => String -> a
和show :: Show a => a -> String
重载show :: Show a => a -> String
你正在调用的show :: Show a => a -> String
。 在这种情况下,由于数字文字,您有fromInteger :: Num a => Integer -> a
隐式,以及getTrue :: NewConstraint a => a -> Bool
。 您必须至少指定a
= Identity b
,因此类型Num b => b
仍然不明确,但Num
可以是默认值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.