4

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) => a -> b変わりIntegerます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

それが効率的か正しいかはわかりませんが、私が試したケースではうまくいきました。


私の主な質問は次の2つだと思います。

  • Elm はリスト内包表記をサポートしていますか? (私はちょうど使用すると思いますmap
  • maybe配列の例で型を回避する方法は?
  • head ( drop n x)リストの n 番目の要素を取得するために呼び出すのは効率的ですか?
4

2 に答える 2

5

Elm はリスト内包表記をサポートしておらず、今後もサポートしません: https://github.com/elm-lang/Elm/issues/147

Evan が参照しているスタイル ガイドには、「マップ、フィルター、およびフォールドを優先する」と記載されているため、「マップを使用して:

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"

于 2014-08-11T22:32:22.080 に答える
3

私は Elm についてよく知らないので、リスト内包表記をサポートしているかどうかについては答えられません (いずれにしても、Google 経由で何かを見つけることはできませんでした) が、他の 2 つの質問には答えることができます。

Array の例で Maybe 型を回避するにはどうすればよいですか?

の型はArray.getです。これは、またはをInt -> Array a -> Maybe a返すことを意味します。ここで、 は指定されたインデックスの値です。これらの操作の 1 つの結果を別の操作にフィードしたい場合、Haskell では次のようにすることができます。NothingJust xx

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

または do 表記を使用:

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

ただし、簡単な検索から、Elm はすべてのモナド型をサポートする場合とサポートしない場合があるようですが、これを回避するために case ステートメントを使用できることを願っています (あまり面白くありません)。

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

実際、これを一般的に行う関数を作成することをお勧めします。これは、Haskellの>>=forの直接のクローンにすぎません。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)複雑になります。つまり、リストから th 要素nを取得するために手順が必要です。n配列には異なる構造があり、対数時間でインデックスを作成できるため、大幅に高速になります。小さなリスト (< 100 要素) の場合、これは実際には問題になりませんが、100 または 1000 を超える要素を取得し始めると、ボトルネックになり始めます。リストは、一般的により便利であるため、最速である必要のない単純なコードに最適です。さて、これが Elm でどのように正確に変換されるかはわかりませんが、Elm はそれらを Javascript 配列に変換する可能性があります。これは真の配列であり、O(1)時間。Elm がコンパイル後に Haskell リストの独自のバージョンを使用する場合、それでも速度が低下します。

于 2014-08-11T18:22:17.337 に答える