【问题标题】:elm list comprehensions, retrieving the nth element of a listelm 列表推导,检索列表的第 n 个元素
【发布时间】:2014-08-11 17:21:29
【问题描述】:

当我注意到Elm 不支持列表推导时,我正试图在 Elm 中模拟魔方。在 Haskell 甚至 Python 中,我会写如下内容:

ghci> [2*c | c <- [1,2,3,4]]

[2,4,6,8]

我在 Elm 中找不到方法。我必须写的实际列表理解是(在 Haskell 中):

ghci> let x = [0,1,3,2]
ghci> let y = [2,3,1,0]
ghci> [y !! fromIntegral c | c <- x]

[2,3,0,1]

fromIntegral :: (Integral a, Num b) =&gt; a -&gt; bInteger 变成 Num

在 Elm 中,我尝试使用数组:

x = Array.fromList [0,1,3,2]
y = Array.fromList [2,3,1,0]
Array.get (Array.get 2 x) y

我开始遇到Maybe 类型的困难:

Expected Type: Maybe number
Actual Type: Int

事实上,我必须查一下它们是什么。我没有解决可能的问题,而是对列表做了一些事情:

x = [0,1,3,2]
y = [2,3,1,0]

f n = head ( drop n x)
map f y

我不知道这是否有效或正确,但它在我尝试过的情况下有效。


我想我的两个主要问题是:

  • Elm 是否支持列表推导? (我想只是使用map
  • 如何绕过数组示例中的maybe 类型?
  • 调用head ( drop n x) 获取列表的第n 个元素是否有效?

【问题讨论】:

    标签: list haskell maybe elm


    【解决方案1】:

    Elm 不支持列表推导:https://github.com/elm-lang/Elm/issues/147

    Evan 提到的样式指南说“更喜欢地图、过滤器和折叠”,所以.. 使用 `map:

    map ((y !!).fromIntegral) x
    

    map (\i-> y !! fromIntegral i) x
    

    评论者指出 (!!) 不是有效的 Elm(它是有效的 Haskell)。我们可以将其定义为:

    (!!) a n = head (drop n a),总函数。

    或许
    (!!) a n = case (head (drop n a)) of Just x -> x Nothing -> crash "(!!) index error"

    【讨论】:

    • 嗨! !! 运算符是什么意思?那是有效的榆树吗?
    • 好问题。它是 Haskell 中的索引运算符。从来没有在榆树看到过。也许回答者只是认为 OP 会定义它。不过,我认为如果指出这一点,答案会好很多:答案应该显示如何在 Elm 中定义 !! 或说明它来自哪个包。
    • 你是对的,它不是有效的 Elm。 (!!) a n = head (drop n a) 是一个定义,一个总函数。或者也许
      (!!) a n = case (head (drop n a)) of
      ` Just x -> x`
      ` Nothing -> crash "(!!) index error"`
    【解决方案2】:

    我对 Elm 了解不多,所以我无法回答它是否支持列表推导(无论哪种方式都无法通过 Google 找到任何关于它的信息),但我可以回答您的其他两个问题。

    如何绕过 Array 示例中的 Maybe 类型?

    Array.get 的类型是Int -&gt; Array a -&gt; Maybe a,这意味着它返回NothingJust x,其中x 是给定索引处的值。如果你想将其中一个操作的结果提供给另一个,在 Haskell 中你可以这样做

    Array.get 2 x >>= \i -> Array.get i y
    

    或者用 do 表示法:

    do
        i <- Array.get 2 x
        Array.get i y
    

    但是,从快速搜索来看,Elm 可能支持也可能不支持所有 monadic 类型,但希望您仍然可以使用 case 语句来解决这个问题(这不是很有趣)

    case Array.get 2 x of
        Nothing -> Nothing
        Just i  -> Array.get i y
    

    事实上,我建议您编写一个函数来为您执行此操作,它只是在 Haskell 中为 Maybe 直接克隆 &gt;&gt;=

    mayBind :: Maybe a -> (a -> Maybe b) -> Maybe b
    mayBind Nothing  _ = Nothing
    mayBind (Just x) f = f x
    

    那么你可以把它当作

    Array.get 2 x `mayBind` (\i -> Array.get i y)
    

    调用head (drop n x)获取列表的第n个元素是否有效?

    没有,但也不是直接索引,相当于head . drop n。对于列表,索引将始终为O(n) 复杂度,这意味着需要n 步骤才能从列表中获取nth 元素。数组具有不同的结构,这使它们能够以对数时间进行索引,这明显更快。对于小列表(O(1) 时间进行索引。如果 Elm 在编译后使用它自己的 Haskell 列表版本,那么您仍然会遇到速度变慢的情况。

    【讨论】:

    • 你的mayBind函数相当于Maybe.andThen
    猜你喜欢
    • 2018-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    • 2023-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多