4

インデックス演算子のように機能する次の関数があります。

let {
  index :: [a]->Int->Maybe a
  index [] i = error "Empty list"
  index l i = if i <= ((length l) - 1) && i >= 0 then 
      Just(l !! i) 
    else
      error "Index out of bounds"
}

さて、最初はこれを使用せずに書きましたJust(そして、グーグルの後でもそれが何であるかはまだわかりません):

let {
  index :: [a]->Int->Maybe a
  index [] i = error "Empty list"
  index l i = if i <= ((length l) - 1) && i >= 0 then
      (l !! i) 
    else
      error "Index out of bounds"
}

私にとって、上記の機能は完全に理にかなっています。ここには、「ジェネリック型」のリストを受け入れる関数とaIntインデックスでありMaybe、型の値を返すaか、ランタイム例外をスローする関数があるためです。ただし、GHCiがこれを教えてくれるところが少しわかりません:

<interactive>:1:120:
Couldn't match type `a' with `Maybe a'
  `a' is a rigid type variable bound by
      the type signature for index :: [a] -> Int -> Maybe a
      at <interactive>:1:34
Expected type: [Maybe a]
  Actual type: [a]
In the first argument of `(!!)', namely `l'
In the expression: (l !! i)

では、なぜ GHCi は の型と混同され、型のlリストを期待しているのMaybe aでしょうか? 最後に、どのようJustに問題を解決しますか?

4

3 に答える 3

6

型注釈で、関数indexが を返すことを具体的に述べましたMaybe a

多分Haskellで定義されたデータ型です:

data Maybe a = Just a | Nothing

つまり、 と の 2 つの値コンストラクターがJust :: a -> Maybe aありNothing :: Maybe aます。したがって、関数が正しく機能するためには、 aJust aまたは aを返す必要がありNothingます。

これはまた、少し考えてエラー ステートメントを削除し、実際のエラーをエンコードしてNothing(つまり、範囲外で、ここには要素がありません!)、意味がある場合にのみ結果を返すことができる必要があることも意味しますJust a

于 2012-07-26T20:52:57.413 に答える
2

indexasの戻り値の型を GHC に伝えましMaybe aた。つまり、(l !! i)(によって返される値index) は 型でなければなりませんMaybe a

(l !! i)はリストから単一の要素を選択するため、その要素の 1 つが であるためには が型でなければならないことlを意味します。l[Maybe a]Maybe a

しかしlは への最初の引数でindexあり、GHC に型付けされていることも伝えています[a]

それはまさにあなたの間違いです。GHC はインデックスを にコンパイルして[Maybe a]を取得しようとしていますMaybe aが、代わりに、インデックスされているものが であることがわかりました[a]

Justこれを修正する理由は、それJustが type であるためa -> Maybe aです。したがって、あなたが と言うとJust (l !! i)、GHC はあなたが a にインデックスを付けて[a]を取得しa、それを適用Justして結果が になるのMaybe aを期待どおりに見るようになりました。

于 2012-07-27T03:50:34.777 に答える
1

ドキュメントから、Data.Maybe :

Maybe 型はオプションの値をカプセル化します。a 型の値 a 型 a の値が含まれているか (Just a として表される)、空である (Nothing として表される) 可能性があります。

タイプを探している場合、関数は、またはMaybe Intを返します。NothingJust Int

これは単純な種類のエラー モナドであり、すべてのエラーは Nothing で表されます。

基本的にNothingが返された場合は、関数が結果を見つけることができないという結果になった何かが発生しています。Just修飾子を使用すると、これらの型を操作できますMaybe

于 2012-07-26T20:53:34.573 に答える