Map function in Haskell

38,253

If you check the type of the map function then you see:

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

So you need a function that takes one parameter, but yours takes two. You have to use

shiftLetters letters shift = map (flip shiftLetter $ shift) letters

or

shiftLetters letters shift = map (`shiftLetter` shift) letters

Pointless style:

shiftLetters = flip $ map . flip shiftLetter
Share:
38,253
Eddie
Author by

Eddie

Updated on July 09, 2022

Comments

  • Eddie
    Eddie almost 2 years

    As far as I understand map in Haskell takes a function and a List and applies that function to every element in that list before creating a new list with the function applied to each member.

    Trying it out, this works fine with really simple functions like (+5) so it works fine if I type:

    map (+7) [2,8,9,3]
    

    I get:

    [9,15,16,10]
    

    However this doesn't work with functions that I have created. Say I have made a function shiftLetter whose type declaration is:

    shiftLetter :: Char -> Int -> Char
    

    (with Int shifting how far along the letter returned is)

    If I make a new function to do it with more than one letter and type:

    shiftLetters :: String -> Int -> Char
    shiftLetters letters shift = map shiftLetters "AKHLKHN"
    

    I get errors, why is this?

  • Eddie
    Eddie over 10 years
    Because shiftLetters takes a String then an Int?
  • Eddie
    Eddie over 10 years
    Okay thanks but I've never seen flip or $ before? What are they for?
  • Phil
    Phil over 10 years
    or you can do (`shiftLetter` shift) instead of (flip shiftLetter $ shift)
  • Benjamin Hodgson
    Benjamin Hodgson over 10 years
    The type system doesn't prevent you from mapping functions of more than one variable. (In fact, in the 'applicative' style it's very common.) map shiftLetters is a perfectly valid expression, with a type of String -> [(Int -> Char)].
  • Eddie
    Eddie over 10 years
    Trying this I get: Syntax error on 'shiftLetter' Perhaps you intended to use -XTemplateHaskell
  • Thomas Bartscher
    Thomas Bartscher over 10 years
    shiftLetter takes a Char, not a String. Note that String is the same as [Char] which is different from Char.
  • Antal Spector-Zabusky
    Antal Spector-Zabusky over 10 years
    @Eddie: The space after $ is important.
  • Eddie
    Eddie over 10 years
    I know! Sorry the functions have very similar names. shiftLetter takes a Char but shiftLetters takes a String?
  • Eddie
    Eddie over 10 years
    I meant for Phil's function namely: ('shiftLetter' shift).
  • Eddie
    Eddie over 10 years
    Also, what do I do if say shiftLetter(s) took more than 2 arguments? Say if shiftLetter type definition was: Char -> String -> Int -> Char and shiftLetters: String -> String -> Int -> String?