2012-01-05 6 views
15

は、私は次のようstripPrefixBy機能を実装したいです。 stripPrefixByのタイプを実装したいのですがどうすればいいですか?高いランク付けimpredicative種類

+0

関連するq/a:http://stackoverflow.com/questions/19982295/practical-implications-of-runst-vs-unsafeperformio – crockeea

答えて

20

あなたの署名の問題はstripPrefixByに渡されたリストには、引数として特定を取る関数のリストとして宣言した後、任意のB発信者ピックのためMaybe bを生産していることです。リスト内の関数が返される唯一の値は,NothingおよびJust ⊥です。

すなわち、そこに、forallコンストラクタの種類に適用されます。impredicative多型を使用した場合、forallは、それが存在量化タイプでない同じことを意味しない、と言うことです

data MyType = forall a. Foo a 
Foo :: forall a. a -> MyType 

しかし、ここでは、その機能は文字通りタイプforall b. a -> Maybe bでなければならないと言っています。なぜあなたはそれをしたいです」、

stripPrefixBy :: [exists b. a -> Maybe b] -> [a] -> Maybe [a] 
5

別の応答があると、私はUHCはあなたが直接欲しい種類を表すサポートしていることを信じてい

{-# LANGUAGE ExistentialQuantification #-} 

data Pred a = forall b. Pred (a -> Maybe b) 

stripPrefixBy :: [Pred a] -> [a] -> Maybe [a] 
stripPrefixBy [] xs = Just xs 
stripPrefixBy _ [] = Nothing 
stripPrefixBy (Pred p:ps) (x:xs) = case p x of 
    Just _ -> stripPrefixBy ps xs 
    Nothing -> Nothing 

res :: Maybe String 
res = stripPrefixBy [Pred $ const (Just 0), Pred Just] "abc" 

wantThisToBeTrue :: Bool 
wantThisToBeTrue = case res of 
    Just "c" -> True 
    _ -> False 

:ここ

は実存タイプを使用して補正例ですそのタイプを持っているのですか? "あなたはすべて同じ結果型を持つ関数の一覧(stripPrefixByの最初の引数)を制約するために満足している場合は、例えば

res :: Maybe String 
res = stripPrefixBy [const (Just undefined), Just] "abc" 

を使用して、stripPrefixByに、次のHaskell98タイプ与えることができます:

stripPrefixBy :: [a -> Maybe b] -> [a] -> Maybe [a] 

等価的に、あなたはあなたにも述語のリストを持っているかもしれないので、最初の引数の関数の結果は、(他に何もタイプ「b」を言及していない)を使用することができないことを観察することができた:

stripPrefixBy :: [a -> Bool] -> [a] -> Maybe [a] 
stripPrefixBy [] xs = Just xs 
stripPrefixBy _ [] = Nothing 
stripPrefixBy (p:ps) (x:xs) = case p x of 
    True -> stripPrefixBy ps xs 
    False -> Nothing 

res :: Maybe String 
res = stripPrefixBy (map (isJust.) [const (Just undefined), Just]) "abc" 

isJust :: Maybe a -> Bool 
isJust (Just _) = True 
isJust Nothing = False 

しかし、おそらくこの質問はあなたが持っているより複雑な問題の抽象化であり、より簡単な応答はうまくいかないでしょうか?すべてができるだけシンプルであるべきですが、単純ではありません。