2017-07-17 6 views
0

私はFoldable種類ハスケルの「無限」折り畳み構造のk番目の要素を見つけるには?

safeIndex :: (Foldable t, Integral i) => t a -> i -> Maybe a 
safeIndex = foldr step (const Nothing) 
    where 
    step :: Integral i => a -> (i -> Maybe a) -> i -> Maybe a 
    step x f i = if i == 0 
       then Just x 
       else f (i - 1) 

に取り組んでいます。しかし、それは無限リストのために動作しない機能、safeIndexを定義したいと思います。 foldrが途中で止まるようにするには、最初の引数がstepの場合にのみ停止する必要があるかどうかを判断する必要があります。

無限の構造で機能するように関数を修正することはできますか?そうでない場合は、どのタイプタイルを制限する必要がありますかt

+0

ここで 'forall'を使うのはなぜですか? –

+0

それ以外の場合、 'step'の明示的な型シグネチャはコンパイルされません。 'ScopedTypeVariable'言語拡張を有効にしました: –

+0

' safeIndex [1 ..] 3'は 'Just 4'を出力します。しかし、それは無限のsnocリストでは機能しませんが、最初から「右からインデックスを付ける」のは意味がありません。 –

答えて

1

質問の説明の定義は、実際に無限の組み込みリストに対して既に機能しています。 )(コメントを見てください)

1

Gabriel Gonzalezのfoldl libraryは、あなたの目的に合ったindexgenericIndexフォールドを提供しています。

たとえば、あなたはそのほかに

safeIndex :: (Foldable f, Integral a) => a -> f b -> Maybe b 
safeIndex = fold . genericIndex 

を書くことができ、あなたが投稿したコードは、あなたが何を意図しているようです。

EDIT:「無限リスト」の間隔を置いています。

これは無限リストでも機能しますが、すべてFoldableに定義するのが分かりやすい方法であることはわかりません。

safeIndex' :: Int -> [a] -> Maybe a 
safeIndex' n = listToMaybe . foldr (.) id (replicate n (drop 1)) 

EDIT 2:

スクラッチはその、あなたがオリジナルのポストに持っているものは、どのFoldableのために働くべきです。

+0

ありがとう!これは便利なライブラリですが、無限リストでは機能しません。 –

+0

ああ、あなたは正しい。私は無限のリストについて少し詳しく説明しました。私は醜いアイデアで編集します。 –

関連する問題