如何在Haskell98下编写多态函数
How to code polymorphic functions under Haskell 98
作为训练练习,我编写了一个多态函数来确定给定数字是单个数字还是所有数字列表的素数:
{-# LANGUAGE FlexibleInstances #-}
class PrimeTo a where
ispt :: Integer -> a -> Bool
instance PrimeTo (Integer) where
ispt n d = 0 /= (rem n d)
instance PrimeTo ([Integer]) where
ispt n [] = True
ispt n (x:xs) = (ispt n x) && (ispt n xs)
为了让它工作,我不得不使用 FlexibleInstances,对此我很满意,但很好奇。
在严格的 Haskell98 下,据我所知,我需要在实例定义中添加类型描述符 T:
class PrimeTo a where
ispt :: Integer -> a -> Bool
instance PrimeTo (T Integer) where
ispt n d = 0 /= (rem n d)
instance PrimeTo (T [Integer]) where
ispt n [] = True
ispt n (x:xs) = (ispt n x) && (ispt n xs)
但我不知道用什么代替“T”,我什至不知道在 Haskell 98 下这是否可行。
所以:
- 在 Haskell 98 下这甚至可能吗?
- 如果是,T 会用什么?
T
可以是Integer
或[]
,如下:
class PrimeTo a where
ispt :: Integer -> a -> Bool
instance PrimeTo Integer where
ispt n d = 0 /= (rem n d)
instance PrimeToList a => PrimeTo [a] where
ispt = isptList -- see below
由于最后一个只能约[a]
,所以我们需要一个帮手classPrimeToList
。
这是额外的助手 class 和实例:
class PrimeToList a where
isptList :: Integer -> [a] -> Bool
instance PrimeToList Integer where
isptList n [] = True
isptList n (x:xs) = ispt n x && isptList n xs
顺便说一下,我将使用 all
:
重写最后一个定义
isptList n = all (ispt n)
以上显示了一般技术。在您的具体情况下,您可能可以避免使用助手 class 并使用
class PrimeTo a where
ispt :: Integer -> a -> Bool
instance PrimeTo Integer where
ispt n d = 0 /= (rem n d)
instance PrimeTo a => PrimeTo [a] where
ispt n = all (ispt n)
这也会定义PrimeTo [[Integer]]
、PrimeTo [[[Integer]]]
等,所以它不是像前面那样的完美替代。
作为训练练习,我编写了一个多态函数来确定给定数字是单个数字还是所有数字列表的素数:
{-# LANGUAGE FlexibleInstances #-}
class PrimeTo a where
ispt :: Integer -> a -> Bool
instance PrimeTo (Integer) where
ispt n d = 0 /= (rem n d)
instance PrimeTo ([Integer]) where
ispt n [] = True
ispt n (x:xs) = (ispt n x) && (ispt n xs)
为了让它工作,我不得不使用 FlexibleInstances,对此我很满意,但很好奇。
在严格的 Haskell98 下,据我所知,我需要在实例定义中添加类型描述符 T:
class PrimeTo a where
ispt :: Integer -> a -> Bool
instance PrimeTo (T Integer) where
ispt n d = 0 /= (rem n d)
instance PrimeTo (T [Integer]) where
ispt n [] = True
ispt n (x:xs) = (ispt n x) && (ispt n xs)
但我不知道用什么代替“T”,我什至不知道在 Haskell 98 下这是否可行。
所以:
- 在 Haskell 98 下这甚至可能吗?
- 如果是,T 会用什么?
T
可以是Integer
或[]
,如下:
class PrimeTo a where
ispt :: Integer -> a -> Bool
instance PrimeTo Integer where
ispt n d = 0 /= (rem n d)
instance PrimeToList a => PrimeTo [a] where
ispt = isptList -- see below
由于最后一个只能约[a]
,所以我们需要一个帮手classPrimeToList
。
这是额外的助手 class 和实例:
class PrimeToList a where
isptList :: Integer -> [a] -> Bool
instance PrimeToList Integer where
isptList n [] = True
isptList n (x:xs) = ispt n x && isptList n xs
顺便说一下,我将使用 all
:
isptList n = all (ispt n)
以上显示了一般技术。在您的具体情况下,您可能可以避免使用助手 class 并使用
class PrimeTo a where
ispt :: Integer -> a -> Bool
instance PrimeTo Integer where
ispt n d = 0 /= (rem n d)
instance PrimeTo a => PrimeTo [a] where
ispt n = all (ispt n)
这也会定义PrimeTo [[Integer]]
、PrimeTo [[[Integer]]]
等,所以它不是像前面那样的完美替代。