2012-01-05 8 views
15

मैं निम्नलिखित stripPrefixBy समारोह लागू करना चाहते हैं। मैं जिस प्रकार के पास चाहता हूं उसके साथ stripPrefixBy को कैसे कार्यान्वित कर सकता हूं?उच्चतर स्थान पर रहीं और impredicative प्रकार

+0

संबंधित q/a: http://stackoverflow.com/questions/19982295/practical-implications-of-runst-vs-unsafeperformio – crockeea

उत्तर

20

अपने हस्ताक्षर के साथ समस्या यह है कि सूची stripPrefixBy के लिए पारित कार्य करता है जो एक तर्क के रूप में एक निश्चित एक लेने की एक सूची के रूप में घोषित किया जाता है, और फिर किसी भी फोन करने वाले की पसंद के लिए एक Maybe b उत्पादन है। सूची में कार्यों को केवल , Nothing और Just ⊥ पर लौटने की अनुमति है। वहाँ, forallनिर्माता के प्रकार के लिए आवेदन किया जाता है, यानी

:

जब impredicative बहुरूपता का उपयोग कर, कहने के लिए है कि, forall एक ही बात यह एक existentially मात्रा निर्धारित प्रकार के साथ करता है मतलब यह नहीं है

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

एक और प्रतिक्रिया है

{-# 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 

मेरा मानना ​​है कि UHC प्रकार आप सीधे चाहते व्यक्त समर्थन करता है, "तुम क्यों इसे चाहते हैं:

यहाँ एक अस्तित्व प्रकार का उपयोग कर एक को सही उदाहरण है उस प्रकार के लिए? " आप एक ही परिणाम प्रकार के लिए कार्यों की सूची (stripPrefixBy का पहला तर्क) विवश करने के लिए खुश सब कर रहे हैं, तो आप जैसे

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

उपयोग कर सकते हैं और फिर stripPrefixBy निम्नलिखित Haskell98 प्रकार दे:

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

तुल्य, आप देख सकता है कि पहली बहस में कार्यों के परिणामों का उपयोग नहीं किया जा सकता (कुछ भी नहीं किसी और का उल्लेख है प्रकार "बी") है, तो आप के रूप में अच्छी विधेय की एक सूची हो सकता है:

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 

लेकिन शायद यह सवाल आपके पास एक और जटिल समस्या का अमूर्त है, और सरल प्रतिक्रिया काम नहीं करेगी? सबकुछ जितना संभव हो उतना आसान होना चाहिए, लेकिन कोई आसान नहीं।

संबंधित मुद्दे