elm list comprehensions,检索列表的第n个元素

时间:2014-08-11 17:21:29

标签: list haskell maybe elm

当我注意到Elm不支持列表推导时,我试图在Elm中模拟魔方。在Haskell甚至是Python中,我会写一些类似的东西:

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

[2,4,6,8]

我在榆树找不到路。我必须写的实际列表理解是(在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) => a -> bInteger变为Num

在Elm中,我尝试使用Arrays:

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

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


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

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

2 个答案:

答案 0 :(得分:5)

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"

答案 1 :(得分:3)

我对榆树知之甚少,所以我无法回答它是否支持列表推导(无论是哪种方式都无法通过Google找到任何内容),但我可以回答你的其他两个问题。

  

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

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

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

或者用符号表示:

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

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元素需要n个步骤。数组具有不同的结构,这使得它们以对数时间进行索引,这显着更快。对于小列表(&lt; 100元素),这并不重要,但是一旦你开始获得超过一百或一千个元素,它就开始成为瓶颈。列表非常适合简单的代码,不必是最快的,因为它们通常更方便。现在,我不知道这在Elm中是如何被翻译的,可能是Elm会将它们转换为Javascript数组,这些数组是真正的数组并且可以在O(1)时间内转换为索引。如果Elm在编译后使用自己版本的Haskell列表,那么你仍然会有一个减速。