Haskell,将字符串Map到Maybe a

42fyovps  于 2022-11-14  发布在  其他
关注(0)|答案(2)|浏览(164)

这个问题已经解决了,它是一个从字符串到“Maybe a”的Map,带有如下定义的空、插入、查找函数,我无法理解解决方案。
代码:

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

我想我明白了。
但是insert对我来说很困惑,里面的lambda我不明白,当x从来没有被当作参数的时候,它是如何在等式中使用的,x是从我可以看到的字符串,但是它在任何地方都没有被赋予值。
还有,为什么像这样的一行可以工作并返回“Just 61”lookup "foo" (insert ("foo", 61) empty)

9o685dep

9o685dep1#

当我们说type Map a = String -> Maybe a时,它只是一个类型别名,所以Map a等同于String -> Maybe a。因此,您知道Map a只是一个函数类型String -> Maybe a
因此,当我们说empty :: Map a时,我们想把empty定义为从StringMaybe a的函数,在这个例子中,我们把它定义为\x -> Nothing,这意味着empty是一个空Map,它把每个字符串xMap到Noting
所以我们可以用同样的方法查看insert :: (String, a) -> Map a -> Map a,这个函数的意义就是多增加一个Map关系(即(String, a)对)添加到给定的Map a,并且返回值是包含添加的对的新的Map a。因此,通过模式匹配insert (s, a) msString类型,a的类型为am的类型为Map a。现在我们要构造的结果的类型为Map a。回想一下,Map a就是String -> Maybe a,所以我们要在这里构造一个函数。要构造函数,我们在这里使用lambda表达式。
所以通过使用lambda表达式\x -> if x == s then Just a else m x,我们可以说这个新的Map aString -> Maybe a类型的函数)接受Stringx,并检查它是否等于s(这次插入的字符串)。如果不是s,我们使用旧的Map am)来检查剩下的Map。
该示例可计算为:

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
fnx2tebb

fnx2tebb2#

一个Map a是一个函数; x是该函数的参数,在map中查找一个键就是调用该键上的map。
考虑在Map中查找"foo",然后将"foo"Map到3

lookup "foo" (insert ("foo", 3) empty)
   -- by the definition of lookup
   == (insert ("foo", 3) empty) "foo"
   -- by the definition of insert
   == (\x -> if x == "foo" then Just 3 else empty x) "foo"
   -- apply function to "foo"
   == if "foo" == "foo" then Just 3 else empty "foo"
   -- take the true branch
   == Just 3

现在考虑在同一Map中查找"bar"

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"
   -- take the false branch
   == empty "bar"
   -- by definition of empty
   == (\x -> Nothing) "bar"
   -- apply function to "bar"
   == Nothing

相关问题