NOTIFICATION: These examples are provided for educational purposes. The use of this code and/or information is under your own responsibility and risk. The information and/or code is given ‘as is’. I do not take responsibilities of how they are used. You are welcome to point out any mistakes in my posting and/or leave a comment.

Haskell Signatures

Previously, we saw how to check the type of the function map:

Hugs> :t map
map :: (a -> b) -> [a] -> [b]

Haskell have a peculiar way to express types.

One way to interpreting this is the following:

map :: (a -> b) -> [a] -> [b]
map ::   {- is the function name -}
(a -> b) {- This means that map takes a function as a argument -}
-> [a]   {- This means that map also takes an array of element type a as an argument -}
-> [b]   {- And return an array of elements type b -}

However, Haskell work using currying, therefore the another way to see this is the following:

map :: (a -> b) -> [a] -> [b]
map ::   {- is a function -}
(a -> b) {- that takes a function as a argument and return a new function (we called map_1) -}
-> [a]   {- This new function (map_1) will take an array of type a as an argument -}
-> [b]   {- and will return an array of element of type b -}

In Haskell, currying is supported in order to support first-class functions. For example:

  1. Lets assume a function takes two arguments; however, only one argument will be supplied
  2. The function will be “curried” which means that  it will produce a function of one argument (one that is not supplied)
  3. Therefore we could see it in this way:
    fn :: a -> b -> c

    where fn(a) yields a new function

    fn' :: b -> c

    in which fn'(b) is called to produce c

For example, lets say we wish to obtain the square root of the values 2 and 3 which are in a list, and return a new list with the results:

[2, 3] => [1.41..., 1.73...]

We can use map together with the function sqrt (square root)!
If we check the type of sqrt we will find that:

Hugs> :t sqrt
sqrt :: Floating a => a -> a

This is a function that takes an element of type a as argument and return an element of type a as a result.
If we use it together with map, we obtain:

Hugs> :t map sqrt
map sqrt :: Floating a => [a] -> [a]

This means that when map takes sqrt function as a parameter, it will create a new function that will take an array of type a and return an array of type a.

Now let see it in action:

Hugs> map sqrt [2, 3]
[1.4142135623731,1.73205080756888]

Now, lets analyse what could be happening internally in Haskell when this command line is executed:

  1. The code of map is the follow:
    -- Map and append
    map :: (a -> b) -> [a] -> [b]
    map f []     = []
    map f (xMads) = f x : map f xs
  2. The code of sqrt is the follow:
    class  (Fractional a) => Floating a  where
    ...
    exp, log, sqrt      :: a -> a
    (**), logBase       :: a -> a -> a
    ...
    x ** y           =  exp (log x * y)
    sqrt x           =  x ** 0.5

When we execute:

> map sqrt [2, 3]

  1. map sqrt [2, 3] 

    match with

    > map f (xMads)
  2. Therefore,
    f x : map f xs

    is executed in which f is sqrt, x is the first element of the list, and xs is the rest of the list

    sqrt 2 : map sqrt [3]
  3. Then
    map sqrt [3]

    match again
    f x : map f xs

    and is executed again to  obtain

    sqrt 2 : sqrt 3 : map sqrt []
  4. map sqrt []
    match
    map f [] = []
    obtaining
    []
  5. Then we obtain
    sqrt 2: sqrt 3 : [] 
  6. Finally, the functions are executed and we obtain
    1.4142135623731 : 1.73205080756888 : [] 

    which returns

    [1.4142135623731, 1.73205080756888]

The following are some examples (fn means function) of types:

  1. fn is just a value:
    fn :: x
  2. fn return a list of ys
    fn :: x -> [y]
  3. fn return a typle of (y, z)
    fn :: x -> (y, z)
  4. fn is a higher order function. It takes a function for argument (b->c) as an input an return a function Foo
    fn :: (b -> c) -> Foo
  5. fn is an input/output action tha return an int value
    fn :: x -> IO Int

© 2010, Alejandro G. Carlstein Ramos Mejia. All rights reserved.

Share

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.

*

Click to Insert Smiley

SmileBig SmileGrinLaughFrownBig FrownCryNeutralWinkKissRazzChicCoolAngryReally AngryConfusedQuestionThinkingPainShockYesNoLOLSillyBeautyLashesCuteShyBlushKissedIn LoveDroolGiggleSnickerHeh!SmirkWiltWeepIDKStruggleSide FrownDazedHypnotizedSweatEek!Roll EyesSarcasmDisdainSmugMoney MouthFoot in MouthShut MouthQuietShameBeat UpMeanEvil GrinGrit TeethShoutPissed OffReally PissedMad RazzDrunken RazzSickYawnSleepyDanceClapJumpHandshakeHigh FiveHug LeftHug RightKiss BlowKissingByeGo AwayCall MeOn the PhoneSecretMeetingWavingStopTime OutTalk to the HandLoserLyingDOH!Fingers CrossedWaitingSuspenseTremblePrayWorshipStarvingEatVictoryCurseAlienAngelClownCowboyCyclopsDevilDoctorFemale FighterMale FighterMohawkMusicNerdPartyPirateSkywalkerSnowmanSoldierVampireZombie KillerGhostSkeletonBunnyCatCat 2ChickChickenChicken 2CowCow 2DogDog 2DuckGoatHippoKoalaLionMonkeyMonkey 2MousePandaPigPig 2SheepSheep 2ReindeerSnailTigerTurtleBeerDrinkLiquorCoffeeCakePizzaWatermelonBowlPlateCanFemaleMaleHeartBroken HeartRoseDead RosePeaceYin YangUS FlagMoonStarSunCloudyRainThunderUmbrellaRainbowMusic NoteAirplaneCarIslandAnnouncebrbMailCellPhoneCameraFilmTVClockLampSearchCoinsComputerConsolePresentSoccerCloverPumpkinBombHammerKnifeHandcuffsPillPoopCigarette