para
とは何の問題もありません。リストにしてrecursion-schemes
せずに専門の明確化のために
import Data.Functor.Foldable
tails :: [a] -> [[a]]
tails = para (\case Nil -> [[]]; Cons a (as, res) -> (a : as) : res)
、::ちょうど頭と各Cons
段階で尾をバックCONS
para :: (a -> [a] -> b -> b) -> b -> [a] -> b
para f z [] = z
para f z (a:as) = f a as (para f z as)
tails :: [a] -> [[a]]
tails = para (\a as res -> (a : as) : res) [[]]
をしかし、あなたは、より一般的になりたい場合は、それほど素敵para
製剤は便利来る:
import qualified Data.Functor.Foldable as Rec (Foldable)
tails :: (Rec.Foldable t, Base t ~ Prim [a]) => t -> [t]
tails as = as : para (\case Nil -> []; Cons a (as, res) -> as : res) as
これはいつものようにリストのために働くが、あなたはまた、type instance Base t = Prim [a]
を与えることができます他のt
-sとFoldable
インスタンスと一緒に使用し、同様に使用します。
代わりに、我々は制約を導入する費用で最初のtails
の定義を維持することができます:
tails' :: (Unfoldable t, Rec.Foldable t, Base t ~ Prim [a]) => t -> [t]
tails' = para (\case Nil -> [embed Nil]; Cons a (as, res) -> embed (Cons a as) : res)
各project
ためにファンクタのfixpointsのための逆embed
があるはずですので、これは、あまりにも悪いことではありませんとにかく、Foldable
とインスタンスは自然にペアになります。
私は再帰-制度の面でバージョンが必要です私の実際のケースは 'List'ではなく、再帰スキームのスタイル構造であるからです。 AIUI再帰スキーム 'para'は、あなたの例の' b'パラメータを持たない 'para :: Foldable t =>(Base t(t、a) - > a) - > t - > a'です。あなたが 'tfa = Maybe(a、f)'( 'Base t'が' 't' =' 't'')であれば' 'tails''と呼ばれるこの' 'para''私が間違っていない限り 'List'と同型ですが)他の' t'でも呼び出すことができますか? – lmm
@lmm編集を参照してください。私はこれがあなたが意味するものだと願っています。 –
'Prim'は' List'特有のものですが、私はリスト以外のデータ構造でも動作するバージョンを望んでいますが、必ずしも 'Base t〜Prim [a]' ?私が考えている関数は、追加の制約を必要とすべきではありません。私は、有効と思われる実装で質問を更新しました(しかし、私は標準的な関数になると思います。バージョン)。 – lmm