简体   繁体   中英

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:

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

Under strict Haskell 98, as I understand it, I would need to add a type descriptor, T , to the instance definitions:

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.

So:

  1. Is this even possible under Haskell 98?
  2. If so, what would be used for T?

T can be Integer or [] , as folllows:

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 . Here's the additional helper class and instance:

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 :

    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 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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