addOne(int x){ return x + 1;}

addOne(double x) { return x + 1.0;}

Here, addOne works on different types, but is still the same function name. This is called Overloading, and it's somewhat more difficult to do in Haskell. In order to overload functions, you will need to define a

*Typeclass*(With the FlexibleInstances Program) to work on the types you want. You can indeed get this to work on generics.

To get this to work, we'll use an example. Think of the function "after". If you said after "profectium" 'f' , you would expect to get "ectium". The type signature for this function is after :: (Eq a) => [a] -> a -> [a]. However, there are cases where you may supply a list to the second argument of after, like in this example: after "profectium" "pro" in order to get the same output. This last example could be useful for sanitation purposes, and to avoid false positives.

The typeclass to get these two functions work will be called "Continuous". Here is the class definition:

class Continuous list part where

after :: list -> part -> list

In both instances of after, you take two arguments and return a sublist of a greater argument. So in order to become part of class Continuous, they have to satisfy an implementation of this function. To make out lives easier, we can use generics instead of individual types in our instance declarations. Everything that is part of the Eq typeclass will automatically qualify for class Continuous.

Here are some helper functions, ignore them if you're unconcerned with implementation specifics:

sub :: (Eq a) => [a] -> Int -> [a]

sub [] _ = []

sub x 0 = x

sub (x:xs) c = sub xs (c - 1)

pos :: (Eq a) => [a] -> a -> Int

pos [] _ = 0

pos (x:xs) c

| x == c = 0

| otherwise = 1 + pos xs c

These will be used to define the after functions. The two headers for after are:

instance (Eq a) => Continuous [a] a

instance (Eq a) => Continuous [a] [a]

This is barring the implementations. Because of the requirements pos (and, by proxy, sub) to have the Eq typeclass, we constrain it in the instance declaration. We also set this up to work with Generics. This will now work. The full file text for the After library is as follows:

{-# LANGUAGE FlexibleInstances #-}

{-# LANGUAGE MultiParamTypeClasses #-}

module Cookbook.Continuous(

sub :: (Eq a) => [a] -> Int -> [a]

sub [] _ = []

sub x 0 = x

sub (x:xs) c = sub xs (c - 1)

pos :: (Eq a) => [a] -> a -> Int

pos [] _ = 0

pos (x:xs) c

| x == c = 0

| otherwise = 1 + pos xs c

class Continuous list part where

after :: list -> part -> list

instance (Eq a) => Continuous [a] a where

after x c = sub x (1+(pos x c))

instance (Eq a) => Continuous [a] [a] where

after [] _ = []

after x c

| take (length c) x == c = sub x ((length c))

| otherwise = after (tail x) c

Note the language pragmas at the top. They are required for this to work. Pragmas just enable features of ghc that are turned off by default.

## No comments:

## Post a Comment