アイデアは、全体の長さを計算せずにリストの長さを Int と比較する「遅延」長さ関数を実装することです。
{-# LANGUAGE DeriveFunctor
, TypeFamilies
, FlexibleInstances #-}
import Data.Functor.Foldable
type instance Base Int = Maybe
これで、Foldable / Unfoldable を持つことができます
instance Foldable Int where
project 0 = Nothing
project x = Just (x-1)
instance Unfoldable Int where
embed Nothing = 0
embed (Just x) = x+1
[a] を Base Int Int に変換したい:
leng :: [a] -> Base Int Int
leng = ana phi where
phi :: [a] -> Base Int [a]
phi [] = Nothing
phi (_:t) = Just t
しかし、これはうまくいきません。[a] と不平を言う -> Base (Maybe Int) [a] は phi の型として期待されます。理由がわかりません。
それがうまくいった場合、私は比較することができます:
gt = curry $ hylo psi phi where
phi (Just _, Nothing) = Left True
phi (Nothing, _) = Left False
phi (Just t, Just n) = Right (t, n)
psi (Left t) = t
psi (Right t) = t
main = print $ (leng [1..]) `gt` (ana project 4)
長さの何が問題になっていますか?