在类型类中重载 Show 和 Num 会使执行无限期挂起
Overloading Show and Num in typeclass makes execution hang indefinitely
我正在对 Haskell 进行分配,并且几乎解决了它。感觉好像我错过了最后一步,但无法确定,我做错了什么。
首先是我的任务:
Now, insted of using type synonyms, define data types CountryCode and PhoneNo so that both of them have a value constructor that takes an integer.
Derive an instance for Eq, Ord and Show for PhoneType.
Derive instances for Eq and Ord for CountryCode and PhoneNo and make Show instances for them so that:
CountryCode: print '+' in front of the number.
PhoneNo: print only the number.
Make a function for both of them (toCountryCode and toPhoneNo) that takes an Integer and throws an error if the integer is negative otherwise it creates the value.
If CountryCode is negative, the error should be "Negative country code" and if PhoneNo is negative, the error should be "Negative phone number" and you should follow these literally to pass the automatic testing.
Again, using the record syntax, define Phone type for phone numbers that has only one value constructor with fields
phoneType :: PhoneType,
countryCode :: CountryCode, (This time the type defined as above)
phoneNo :: PhoneNo. (This time the type defined as above)
Derive an instance for Eq and Ord for the record, but for Show make it "pretty-print" the infromation in this form:
e.g. +358 123456789 (WorkLandline)
现在我的任务是:
data PhoneType = WorkLandline|PrivateMobile|WorkMobile|Other deriving (Read,Show,Eq)
newtype PlainString = PlainString String
instance Show PlainString where
show (PlainString s) = s
--instance Num Int where
-- (*)=int_times
-- (+)=int_plus
data CountryCode = CountryCode
{
cCode :: Int
} deriving (Read,Eq)
instance Show CountryCode where
show (CountryCode a)=(show (PlainString "+")) ++ (show a)
instance Num CountryCode where
(*) a b=a*b
(+) a b=a+b
(-) a b=a-b
fromInteger x=fromInteger x
toCountryCode :: Int->CountryCode
toCountryCode ccode
| ccode<0=error "Negative country code"
|otherwise = CountryCode ccode
data PhoneNo = PhoneNo
{
pNo :: Int
} deriving (Read,Eq)
instance Show PhoneNo where
show (PhoneNo a)=show a
instance Num PhoneNo where
(*) a b=a*b
(+) a b=a+b
(-) a b=a-b
fromInteger x= fromInteger x
toPhoneNo :: Int -> PhoneNo
toPhoneNo pno
| pno<0=error "Negative phone number"
|otherwise = PhoneNo pno
data Phone = Phone
{
phoneType :: PhoneType,
countryCode :: CountryCode,
phoneNo :: PhoneNo
} deriving (Read,Eq)
instance Show Phone where
show (Phone a b c)=show a
makePhone :: PhoneType -> CountryCode -> PhoneNo -> Phone
makePhone phonetype countrycode phoneno
|otherwise = Phone phonetype countrycode phoneno
这个版本有点适用于:
makePhone 其他 1 1
, 显示 其他.
但是,如果我将其修改为:
显示 (Phone a b c)=显示 b
或者按照任务中的要求使 show 正常 - 程序无限期挂起。同样适用于 show c
我做错了什么?
实施如:
instance Num CountryCode where
(*) a b = a*b
(+) a b = a+b
(-) a b = a-b
fromInteger x = fromInteger x
没有多大意义,因为您在这里定义可以将两个 CountryCode
加在一起,通过将它们加在一起...因此导致无限递归。
您可以定义加法、乘法等,方法是解包包装在 CountryCode
数据构造函数中的值,执行算术运算,然后将其包装在 CountryCode
数据构造函数中:
instance Num CountryCode where
<strong>CountryCode</strong> a * <strong>CountryCode</strong> b = <strong>CountryCode</strong> (a * b)
<strong>CountryCode</strong> a + <strong>CountryCode</strong> b = <strong>CountryCode</strong> (a + b)
<strong>CountryCode</strong> a - <strong>CountryCode</strong> b = <strong>CountryCode</strong> (a - b)
fromInteger x = <strong>CountryCode</strong> (fromInteger x)
instance Num PhoneNo
也是如此。
您可以使用 GeneralizedNewtypeDeriving 派生以下实例,但它们必须是 newtype
才能起作用:
Show PlainString
Num CountryCode
Show PhoneNo
、Num PhoneNo
我建议使用 DerivingStrategies 明确说明您使用的是哪种推导方法:stock
使用 GHC 内置的推导机制,newtype
使用底层实例输入(Show String
、Show Int
和 Num Int
)。
{-# Language DerivingStrategies #-}
{-# Language GeneralizedNewtypeDeriving #-}
newtype CountryCode = CountryCode { cCode :: Int }
deriving
stock (Eq, Read)
deriving
newtype Num
newtype PlainString = PlainString String
deriving
newtype Show
newtype PhoneNo = PhoneNo { pNo :: Int }
deriving
stock (Eq, Read)
deriving
newtype (Num, Show)
我正在对 Haskell 进行分配,并且几乎解决了它。感觉好像我错过了最后一步,但无法确定,我做错了什么。
首先是我的任务:
Now, insted of using type synonyms, define data types CountryCode and PhoneNo so that both of them have a value constructor that takes an integer. Derive an instance for Eq, Ord and Show for PhoneType. Derive instances for Eq and Ord for CountryCode and PhoneNo and make Show instances for them so that: CountryCode: print '+' in front of the number. PhoneNo: print only the number. Make a function for both of them (toCountryCode and toPhoneNo) that takes an Integer and throws an error if the integer is negative otherwise it creates the value.
If CountryCode is negative, the error should be "Negative country code" and if PhoneNo is negative, the error should be "Negative phone number" and you should follow these literally to pass the automatic testing.
Again, using the record syntax, define Phone type for phone numbers that has only one value constructor with fields
phoneType :: PhoneType,
countryCode :: CountryCode, (This time the type defined as above)
phoneNo :: PhoneNo. (This time the type defined as above)
Derive an instance for Eq and Ord for the record, but for Show make it "pretty-print" the infromation in this form: e.g. +358 123456789 (WorkLandline)
现在我的任务是:
data PhoneType = WorkLandline|PrivateMobile|WorkMobile|Other deriving (Read,Show,Eq)
newtype PlainString = PlainString String
instance Show PlainString where
show (PlainString s) = s
--instance Num Int where
-- (*)=int_times
-- (+)=int_plus
data CountryCode = CountryCode
{
cCode :: Int
} deriving (Read,Eq)
instance Show CountryCode where
show (CountryCode a)=(show (PlainString "+")) ++ (show a)
instance Num CountryCode where
(*) a b=a*b
(+) a b=a+b
(-) a b=a-b
fromInteger x=fromInteger x
toCountryCode :: Int->CountryCode
toCountryCode ccode
| ccode<0=error "Negative country code"
|otherwise = CountryCode ccode
data PhoneNo = PhoneNo
{
pNo :: Int
} deriving (Read,Eq)
instance Show PhoneNo where
show (PhoneNo a)=show a
instance Num PhoneNo where
(*) a b=a*b
(+) a b=a+b
(-) a b=a-b
fromInteger x= fromInteger x
toPhoneNo :: Int -> PhoneNo
toPhoneNo pno
| pno<0=error "Negative phone number"
|otherwise = PhoneNo pno
data Phone = Phone
{
phoneType :: PhoneType,
countryCode :: CountryCode,
phoneNo :: PhoneNo
} deriving (Read,Eq)
instance Show Phone where
show (Phone a b c)=show a
makePhone :: PhoneType -> CountryCode -> PhoneNo -> Phone
makePhone phonetype countrycode phoneno
|otherwise = Phone phonetype countrycode phoneno
这个版本有点适用于: makePhone 其他 1 1 , 显示 其他.
但是,如果我将其修改为: 显示 (Phone a b c)=显示 b 或者按照任务中的要求使 show 正常 - 程序无限期挂起。同样适用于 show c
我做错了什么?
实施如:
instance Num CountryCode where
(*) a b = a*b
(+) a b = a+b
(-) a b = a-b
fromInteger x = fromInteger x
没有多大意义,因为您在这里定义可以将两个 CountryCode
加在一起,通过将它们加在一起...因此导致无限递归。
您可以定义加法、乘法等,方法是解包包装在 CountryCode
数据构造函数中的值,执行算术运算,然后将其包装在 CountryCode
数据构造函数中:
instance Num CountryCode where
<strong>CountryCode</strong> a * <strong>CountryCode</strong> b = <strong>CountryCode</strong> (a * b)
<strong>CountryCode</strong> a + <strong>CountryCode</strong> b = <strong>CountryCode</strong> (a + b)
<strong>CountryCode</strong> a - <strong>CountryCode</strong> b = <strong>CountryCode</strong> (a - b)
fromInteger x = <strong>CountryCode</strong> (fromInteger x)
instance Num PhoneNo
也是如此。
您可以使用 GeneralizedNewtypeDeriving 派生以下实例,但它们必须是 newtype
才能起作用:
Show PlainString
Num CountryCode
Show PhoneNo
、Num PhoneNo
我建议使用 DerivingStrategies 明确说明您使用的是哪种推导方法:stock
使用 GHC 内置的推导机制,newtype
使用底层实例输入(Show String
、Show Int
和 Num Int
)。
{-# Language DerivingStrategies #-}
{-# Language GeneralizedNewtypeDeriving #-}
newtype CountryCode = CountryCode { cCode :: Int }
deriving
stock (Eq, Read)
deriving
newtype Num
newtype PlainString = PlainString String
deriving
newtype Show
newtype PhoneNo = PhoneNo { pNo :: Int }
deriving
stock (Eq, Read)
deriving
newtype (Num, Show)