【问题标题】:SML map functionSML地图功能
【发布时间】:2013-12-31 14:16:41
【问题描述】:

我有这个功能:

map(map(fn x =>[x])) [[],[1],[2,3,4]];

产生:

val it = [[],[[1]],[[2],[3],[4]]]

我不明白这个功能是如何工作的。不是每个地图函数都需要一个函数和一个列表吗?似乎没有足够的论据来实际执行。

如果我跑:

map(fn x =>[x]) [[],[1],[2,3,4]];

我明白了:

val it = [[[]], [[1]], [[2,3,4]]];

这对我来说更有意义,因为它获取列表中的每个元素,并将其包装在另一个列表中。但是当我在上面放另一张地图时,它会改变输出。谁能给我解释一下?谢谢!

【问题讨论】:

    标签: sml smlnj currying partial-application map-function


    【解决方案1】:

    你说:

    我不明白这个功能是如何工作的。不是每个map函数都需要一个函数和一个列表吗?

    好吧,请记住,在标准 ML(以及一般情况下,所有应用语言)中,对于除 1 之外的“n”,没有“n 个参数的函数”之类的东西。但是,可以通过两种方式模拟多个参数

    1. 作为元组或记录的单个参数的函数。通过元组或记录的投影,可以在函数体中恢复原始预期参数。

    2. 作为第一个参数的函数,返回其余参数的函数。

    考虑到这一点,我们在 REPL 中检查map 的类型:

    > map;
    val it = fn: ('a -> 'b) -> 'a list -> 'b list
    

    (我使用 Poly/ML,而不是 SML/NJ,但除了格式问题,输出应该是相同的。)

    没有元组,没有记录。 map 显然采用第二种方法来模拟两个参数的函数:它采用 'a -> 'b 类型的函数并返回 另一个 'a list -> 'b list 类型的函数。

    现在,问题来了:对于任何函数foomap foo 也是一个函数!由于map 可以将any 函数作为参数,因此map foo 本身就是map 的完全合法参数。这意味着map (map foo) 对任何函数foo 进行类型检查。特别是,如果val foo = fn x => [x] 是这样。


    你说:

    似乎没有足够的参数来实际执行。

    如果它进行类型检查,它就会运行。


    你说:

    如果我跑步

    map (fn x => [x]) [[], [1], [2,3,4]]
    

    我明白了

    val it = [[[]], [[1]], [[2,3,4]]];
    

    这对我来说更有意义,因为它获取列表中的每个元素,并将其包装在另一个列表中。但是当我在上面放另一张地图时,它会改变输出。

    让我们在不改变其含义的情况下稍微重构您的代码:

    let
      val foo = fn x => [x]
      val bar = map foo
      val baz = map bar
    in
      baz [[], [1], [2,3,4]]
    end
    

    现在我们可以分析每个函数(foobarbaz)对其参数做了什么:

    1. foo 采用单个元素 x 并将其包装在列表数据构造函数中。
    2. bar 获取一个元素列表,将每个元素包装在一个列表数据构造函数中,并返回一个包含结果包装元素的列表(列表列表)。
    3. baz 获取元素(子)列表的(超)列表,将bar 应用于每个子列表,并返回一个包含结果的列表。

    手动执行所有这些操作,让自己相信结果 [[], [[1]], [[2], [3], [4]]] 确实是正确的。

    【讨论】:

      【解决方案2】:
       map ;
       val it = fn : ('a -> 'b) -> 'a list -> 'b list
      

      所以 map 接受一个函数,该函数再次接受一个列表并给出一个列表。

      所以用函数定义地图

      -fun f x = x+1 ;
      val f = fn : int -> int
      -map f ;
      val it = fn : int list -> int list
      

      现在it 是那种接受列表并返回列表的函数

      - it [1,2] ;
      val it = [2,3] : int list
      

      我觉得地图功能很清楚

      【讨论】:

        猜你喜欢
        • 2014-07-15
        • 1970-01-01
        • 2013-01-13
        • 2013-10-20
        • 1970-01-01
        • 1970-01-01
        • 2010-09-13
        • 2013-11-19
        • 2012-02-01
        相关资源
        最近更新 更多