Home > OS >  Make haskell function accepts itself as parameters
Make haskell function accepts itself as parameters

Time:12-10

I am currently learning haskell, trying to make a function successor either takes in a Num and returns its successor (4 == successor 3) or takes in itself and returns a double successor function (5 == (successor successor) 3).

What would be the correct way to make successor function is a type of its class Successor?

naive Successor class

class Successor a where
    successor :: a -> a


instance Successor Int where
    successor n
        | (==) 1 n = 2
        | otherwise = 1   successor (n - 1)

test code

n :: Int
n = 3
m = successor (successor n)

main = do
    print m -- print 5

needed behavior

n :: Int
n = 3
m = (successor successor) n

main = do
    print m -- print 5

CodePudding user response:

This seems an awful idea to me -- why do you want to write a function working on both numbers and functions?

Anyway, you could achieve what you ask (but probably not what you really want) as follows:

{-# LANGUAGE FlexibleInstances #-}
module Main where

class Successor a where
    successor :: a -> a

instance Successor Int where
    successor n
        | (==) 1 n = 2
        | otherwise = 1   successor (n - 1)

instance Successor (Int -> Int) where
    successor f = f . f

n' :: Int
n' = 3

m1 :: Int
m1 = successor (successor n')

m2 :: Int
m2 = (successor successor) n'

main :: IO ()
main = do
    print m1 -- print 5
    print m2 -- print 5

The definition successor f = f . f works in this specific case, where f = successor, but will likely not produce the expected output in other cases.

We could use some variant like successor f = successor . f. Perhaps this is more useful in general, but it still looks as a bad idea to me.

CodePudding user response:

I agree with chi that this is probably a bad idea, but if you're going to have such a typeclass then I'd make it as general as possible:

class Successor a where
  scs :: a -> a

instance Successor Int where
  scs = succ  -- don't reinvent the wheel

instance Successor a => Successor (c -> a) where
  scs f = scs . f

Then

ghci> scs scs (scs (scs scs)) ((scs scs) scs) scs (scs scs) 0 :: Int
11
  • Related