简体   繁体   English

Haskell 98下如何编写多态函数

[英]How to code polymorphic functions under Haskell 98

As a training exercise, I have written a polymorphic function to determine whether a given number is prime to either a single number or all of a list of numbers:作为训练练习,我编写了一个多态 function 来确定给定数字是单个数字还是所有数字列表的质数:

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

To get this to work, I had to use FlexibleInstances, and I'm happy with that, but curious.为了让它工作,我不得不使用 FlexibleInstances,我对此很满意,但很好奇。

Under strict Haskell 98, as I understand it, I would need to add a type descriptor, T , to the instance definitions:据我了解,在严格的 Haskell 98 下,我需要在实例定义中添加一个类型描述符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)

but I haven't a clue what goes in place of "T", and I don't even know whether this is possible under Haskell 98.但我不知道用什么代替“T”,我什至不知道这在 Haskell 98 下是否可行。

So:所以:

  1. Is this even possible under Haskell 98?在 Haskell 98 下这甚至可能吗?
  2. If so, what would be used for T?如果是这样,T 会使用什么?

T can be Integer or [] , as folllows: 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

Since the last one can only be about [a] , we need a helper class PrimeToList .由于最后一个只能是[a] ,我们需要一个助手 class PrimeToList Here's the additional helper class and instance:这是额外的助手 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

By the way, I'd rewrite the last definition using all :顺便说一句,我会使用all重写最后一个定义:

    isptList n = all (ispt n)

The above shows the general technique.以上显示了一般技术。 In your specific case, you can probably avoid the helper class and use在您的特定情况下,您可能可以避免使用助手 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)

This will also define PrimeTo [[Integer]] , PrimeTo [[[Integer]]] and so on, so it is not a perfect replacement like the previous one.这也会定义PrimeTo [[Integer]]PrimeTo [[[Integer]]]等等,所以它不像之前的那样完美替代。

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

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