This question is already solved, it is a mapping from a String to a "Maybe a", with empty,insert,lookup functions as defined below, i'm unable to understand the solution.
The code:
type Map a = String -> Maybe a
empty :: Map a
empty = \x -> Nothing
insert :: (String, a) -> Map a -> Map a
insert (s, a) m = \x -> if x == s then Just a else m x
lookup :: String -> Map a -> Maybe a
lookup x m = m x
empty and lookup i think i understand.
insert however is puzzling to me,the lambda inside it i don't understand, how is x used in the equality when it is never taken as a parameter, x is from what i can see is a String, but it isn't given a value anywhere.
what would be the resulting function from insert ("foo", 61) empty
how would it be evaluated, and what does x represent?
also why would a line like this work and return "Just 61"
lookup "foo" (insert ("foo", 61) empty)
CodePudding user response:
When we say type Map a = String -> Maybe a
, it is just a type alias, so Map a
is identical to String -> Maybe a
. Thus, you know that Map a
is just a function type String -> Maybe a
.
Therefore, when we say empty :: Map a
, we want to define empty
as a function from String
to Maybe a
. In this example, we have defined it as \x -> Nothing
, which means empty
is an empty map that maps every string x
to Noting
.
So we can look into insert :: (String, a) -> Map a -> Map a
using the same method. The meaning for this function is to add one more mapping relation (i.e., (String, a)
pair) to a given Map a
, and the return value is a new Map a
which contains the added pair.
Therefore, by pattern matching insert (s, a) m
, s
is of type String
, a
is of type a
, and m
is of type Map a
. Now we have to construct the result, which is of type Map a
. Recall that Map a
is just String -> Maybe a
, so we have to construct a function here. To construct a function, we use the lambda expression here.
So by using lambda expression \x -> if x == s then Just a else m x
, we are saying that this new Map a
(function of type String -> Maybe a
) takes a String
x
, and checks if it is equal to s
(the string inserted this time). If it is not s
, we use the old Map a
(m
) to check the remaining mapping.
The example could be calculated as:
lookup "foo" (insert ("foo", 61) empty)
{applying lookup}
= (insert ("foo", 61) empty) "foo"
{applying insert}
= (\x -> if x == "foo" then Just 61 else (empty x)) "foo"
{applying lambda expression, replacing x with "foo"}
= if "foo" == "foo" then Just 61 else (empty "foo")
{applying if_then_else}
= Just 61
CodePudding user response:
A Map a
is a function; x
is the parameter of that function. Looking up a key in a map just means calling the map on the key.
Consider the lookup of "foo"
in a map than maps "foo"
to 3
.
lookup "foo" (insert ("foo", 3) empty)
== (insert ("foo", 3) empty) "foo"
== (\x -> if x == "foo" then Just 3 else empty x) "foo"
== if "foo" == "foo" then Just 3 else empty "foo"
== Just 3
Now consider the lookup of "bar"
in the same map.
lookup "bar" (insert ("foo", 3) empty)
== (insert ("foo", 3) empty) "bar"
== (\x -> if x == "foo" then Just 3 else empty x) "bar"
== if "bar" == "foo" then Just 3 else empty "bar"
== empty "bar"
== (\x -> Nothing) "bar"
== Nothing