2017-04-27 11 views
5

पृष्ठभूमि: मुझे ~ समझ में नहीं आता है और मैं उपयोग के मामले का अनुरोध कर रहा हूं।2 कार्यों के साथ `~` को समझना

को देखते हुए:

{-# LANGUAGE GADTs #-} 

f :: a ~ b => a -> b -> b 
f a b = a 

g :: a -> a -> a 
g a b = a 

मुझे ऐसा लगता है कि दोनों कार्यों के बराबर हैं:

Prelude> :r 
[1 of 1] Compiling Main    (TypeEq.hs, interpreted) 
Ok, modules loaded: Main. 
*Main> f 10 20 
10 
*Main> g 10 20 
10 

क्या परिस्थितियों में यह g से अधिक f उपयोग करने के लिए उपयोगी हो सकता है?

+4

दरअसल के अन्य सूखी-संभावना की तुलना में बेहतर हो सकता है, वहाँ कोई फायदा नहीं है ऐसे मामले में: वे कार्य बराबर हैं। मुझे लगता है कि कुछ उपयोगी सामान देखने के लिए आपको परिवार या जीएडीटी टाइप करने की आवश्यकता है। या शायद $ Data.Typeable.eqT $ एक अच्छा उदाहरण के रूप में मदद कर सकते हैं। – chi

+3

यदि आप सोचते हैं, तो एक बहुत ही उपयोगी तरीके से ~ ~ 'का उपयोग कैसे किया जा सकता है, क्रिस डोन से इस महान ब्लॉग पोस्ट को पढ़ें: http://chrisdone.com/posts/haskell-constraint-trick – Shersh

उत्तर

9
{-# LANGUAGE TypeFamilies #-} 

import GHC.Exts (IsList(..)) 

fizzbuzz :: (IsList l, Item l ~ Int) => l -> IO() 
fizzbuzz = go . toList 
where go [] = return() 
     go (n:m) 
     | n`mod`3==0 = putStrLn "fizz" >> go m 
     | n`mod`5==0 = putStrLn "buzz" >> go m 
     | otherwise = print n >> go m 

फिर

Prelude> fizzbuzz [1..7] 
1 
2 
fizz 
4 
buzz 
fizz 
7 
Prelude> import Data.Vector.Unboxed as UA 
Prelude UA> fizzbuzz (UA.fromList[1..7] :: UA.Vector Int) 
1 
2 
fizz 
4 
buzz 
fizz 
7 

अब आप आपत्ति सकता है कि यह बेहतर एक Foldable बाधा के साथ किया किया जाना चाहिए था, एक सूची में बदसूरत रूपांतरण के बजाय। दरअसल यह नहीं किया जा सका, क्योंकि Unbox बाधा के कारण अनबॉक्स किए गए वैक्टरों में एक फोल्ड करने योग्य उदाहरण नहीं है!

हालाँकि इस बात पर बस के रूप में अच्छी तरह से एक गैर संतुलन संबंधी बाधा के साथ और अधिक अजीब किया जा सकता था किया गया है, अर्थात्

fizzbuzz :: (IsList l, Num (Item l), Eq (Item l), Show (Item l)) 
    => l -> IO() 

कि अधिक सामान्य है, लेकिन यकीनन भी। जब आपको आवश्यकता होती है, प्रैक्टिस में, केवल एक निहित-प्रकार वैसे भी, एक समेकित बाधा एक अच्छी पसंद हो सकती है।

दरअसल, मैं कभी कभी यह सुविधाजनक एक संतुलन संबंधी बाधा में टॉस करने के लिए सिर्फ एक प्रकार हस्ताक्षर अधिक संक्षिप्त बनाने के लिए, लगता है यह थोड़ा दोहराव है: हस्ताक्षर

complicatedFunction :: Long (Awkward (Type a) (Maybe String)) 
       -> [Long (Awkward (Type a) (Maybe String))] 
       -> Either String (Long (Awkward (Type a) (Maybe String))) 

complicatedFunction :: r ~ Long (Awkward (Type a) (Maybe String)) 
      => r -> [r] -> Either String r 
साथ बदला जा सकता

जो

type LAwkTS a = Long (Awkward (Type a) (Maybe String)) 

complicatedFunction :: LAwkTS a -> [LAwkTS a] -> Either String (LAwkTS a) 
संबंधित मुद्दे