0

Here's a snippet of a Haskell program I'm trying to understand:

englishToFrench =  [("the", "le"),("savage", "violent"),("work", "travail"),
         ("wild", "sauvage"),("chance", "occasion"),]

data Entry = Entry {word       :: String,
                    definition :: String,
                    length'    :: Int}
             deriving Show

listOfEntries = map (\(x, y) -> Entry x y (length x)) englishToFrench

Briefly, the program takes a list of String tuples and turns out a list of Entry objects.

However, I don't like the lambda functions in the map and I'd like to create a regular function to replace it.

I attempted this but it is giving me an error that x and y are not in the scope:

entryBuilder x y = Entry x y (length x)

entries = map (entryBuilder x y) englishToFrench

Can anyone tell me how to convert the lambda function and what the general method is?

1 Answer 1

5

Firstly, your entryBuilder function has the wrong type. It should be:

entryBuilder :: (String, String) -> Entry
entryBuilder (x, y) = Entry x y (length x)

while yours has type

String -> String -> Entry

the type of map is

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

since your list type is [(String, String)] you want a function of type

(String, String) -> b

to pass to map.

This is your entryBuilder function, so you can just use

listOfEntries = map entryBuilder englishToFrench

Note that you can use your existing definition of entryBuilder using uncurry:

entryBuilder :: String -> String -> Entry

listOfEntries = map (uncurry entryBuilder) englishToFrench

uncurry has the type

uncurry :: (a -> b -> c) -> ((a, b) -> c)

i.e. it converts a curried function in two arguments into a function with a single pair argument. Since your existing entryBuilder function has type

String -> String -> Entry

uncurry entryBuilder has type

(String, String) -> Entry

which is the function type you require to pass to map.

Sign up to request clarification or add additional context in comments.

3 Comments

In your type definition of map, are you sure the [a]->[b] should be together in brackets (it's a function itself??)
@Imray (a -> b) -> ([a] -> [b]) and (a -> b) -> [a] -> [b] are the same, the function arrow is right-associative.
@Imray - I've added an explanation about uncurry. As for map, I find it helpful to think of it as a function which lifts a 'regular' function over lists (i.e. takes a function from a to b and returns a function from lists of a to lists of b). I find it easier to see map f as producing a function between lists rather than a partial application of a function in two arguments.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.