2017-03-24 9 views
7

उदाहरण के लिए, GHCi में :t ap टाइपिंग कैसे मुझे लगता है कि विशिष्ट उदाहरण के लिए ap के प्रकार के लिए क्वेरी कर सकता है,मैं विशिष्ट प्रकार के क्लास उदाहरण के लिए पॉलीमोर्फिक फ़ंक्शन का प्रकार कैसे प्राप्त कर सकता हूं?

ap :: Monad m => m (a -> b) -> m a -> m b 

परिणाम देता है अगर मैं पहले से ही पता इकाई उदाहरण मैं उपयोग करने के लिए जा रहा हूँ ((->) r) है?

+1

यदि आप केवल कार्यात्मक प्रकार जानना चाहते हैं, तो ['Data.Aviary.Functional'] है (https://hackage.haskell.org/package/data-aviary-0.4.0/docs/Data-Aviary- कार्यात्मक .html)। आपके प्रश्न के लिए, आप विशिष्ट 'एम' टावर में पास करने के लिए TypeApplications का उपयोग करने का प्रयास कर सकते हैं। – Lazersmoke

उत्तर

9

आप पैरामीट्रिक प्रकार निर्दिष्ट करने के लिए visible type application सुविधा का उपयोग कर सकते हैं। आप अधिक रचनात्मक तरीके से कार्यों को देख सकते हैं: में कार्य Haskell न केवल कुछ प्रकार के मानों पर लागू किया जा सकता है, बल्कि उन मानों के प्रकारों पर भी लागू किया जा सकता है। लेकिन टाइप करने के लिए आपको किसी भी तरह निर्दिष्ट करना चाहिए (@ को पूर्ववत करने के साथ) कि आप प्रकार गुजर रहे हैं (क्योंकि प्रकार हास्केल में प्रथम श्रेणी की वस्तुएं नहीं हैं)।

तो यहाँ है कि यह कैसे काम करता है:

λ: :set -XTypeApplications 
λ: :t ap @((->) Int) 
ap @((->) Int) :: (Int -> a -> b) -> (Int -> a) -> Int -> b 

इस तरह के दृष्टिकोण का केवल सीमा है कि आप ghci में टाइप चर का उपयोग नहीं कर सकते हैं, तो आप विशिष्ट प्रकार (r के बजाय Int) का उपयोग करना चाहिए है, लेकिन यह नहीं है बड़ी बात।

उन्नत अनुभाग

ठीक है, वास्तव में आप कर सकते हैं, लेकिन यह मुश्किल है:

λ: :set -XExplicitForAll 
λ: :set -XPartialTypeSignatures 
λ: :set -XScopedTypeVariables 
λ: :{ 
λ| foo :: forall r . _ 
λ| foo = ap @((->) r) 
λ| :} 
<interactive>:28:19: warning: [-Wpartial-type-signatures] 
    • Found type wildcard ‘_’ 
     standing for ‘(r -> a -> b) -> (r -> a) -> r -> b’ 
λ: :t foo 
foo :: (r -> a -> b) -> (r -> a) -> r -> b 

युपीडी: आप वास्तव में प्रकार चर के बजाय प्लेसहोल्डर (another answer देखें) का उपयोग कर सकते हैं। लेकिन यदि आप ऊपर से सटीक नाम उपयोग दृष्टिकोण निर्दिष्ट करना चाहते हैं।

λ: :t ap @((->) _) 
ap @((->) _) :: (t -> a -> b) -> (t -> a) -> t -> b 

/उन्नत अनुभाग

एक और बात इस दृष्टिकोण के बारे में कहने के लिए: यदि आपके कार्यों कई प्रकार पैरामीटर है और आप सही एक निर्दिष्ट करना चाहते हैं आप अधिक कुछ करना चाहिए। bar :: Int -> String -> Double जैसे कुछ फ़ंक्शन में सरल तर्क जैसे बाएं से दाएं एक प्रकार से एक प्रकार बीत जाते हैं।यदि आप bar के पहले तर्क को ठीक करना चाहते हैं तो आपको bar 5 लिखना चाहिए और यदि आप दूसरे को ठीक करना चाहते हैं, तो, आप \n -> bar n "baz" जैसे कुछ लिख सकते हैं लेकिन यह टाइप एप्लिकेशन के साथ काम नहीं करता है। आपको दो चीजों को जानने की जरूरत है:

  1. प्रकारों का आदेश।
  2. वांछित प्रकार कैसे निर्दिष्ट करें।

    λ: :t lift 
    lift :: (Monad m, MonadTrans t) => m a -> t m a 
    

    हम m और t प्रकार चर का उल्लेख कर सकते हैं:

अगले समारोह पर विचार करें। क्योंकि हास्केल में कोई नाम टाइप प्रकार नहीं है (अभी तक) आप :t lift {t=MaybeT} या :t lift {m=IO} दुर्भाग्यवश नहीं लिख सकते हैं। तो दो चीजों पर वापस जाओ।

प्रकारों के क्रम को देखने के लिए आपको कुछ कंपाइलर विकल्पों का उपयोग करना चाहिए। प्रकार के तर्कों का क्रम forall द्वारा निर्दिष्ट किया गया है और आप इसे मैन्युअल रूप से कर सकते हैं। अन्यथा प्रकार पैरामीटर किसी भी तरह संकलक द्वारा क्रमबद्ध किया जाएगा। Mere मनुष्यों lift समारोह के लिए प्रकार के आदेश नहीं देख सकते हैं, लेकिन अगर आप कुछ उच्च स्तर के जादू आप कर सकते हैं के बारे में पता कर रहे हैं:

λ: :set -fprint-explicit-foralls 
λ: :t lift 
lift 
    :: forall {t :: (* -> *) -> * -> *} {a} {m :: * -> *}. 
    (Monad m, MonadTrans t) => 
    m a -> t m a 

और फिर आप @_ का उपयोग करना चाहिए कुछ प्रकार को छोड़ने के लिए:

λ: :t lift @MaybeT 
lift @MaybeT 
    :: forall {a} {m :: * -> *}. Monad m => m a -> MaybeT m a 
λ: :t lift @_ @IO 
lift @_ @IO 
    :: forall {t :: (* -> *) -> * -> *} {a}. 
    MonadTrans t => 
    IO a -> t IO a 
λ: :t lift @_ @_ @Int 
lift @_ @_ @Int 
    :: forall {t :: (* -> *) -> * -> *} {t1 :: * -> *}. 
    (Monad t1, MonadTrans t) => 
    t1 Int -> t t1 Int 

खैर, यह वास्तव में मेरे लिए रहस्य क्यों mforall में के रूप में तीसरे तर्क दिखाया गया है, लेकिन जैसा कि दूसरा पारित किया जाना चाहिए लेकिन मैं अभी भी सब जादू के बारे में पता नहीं कर रहा हूँ है।

2

यह सिर्फ एक हैक है, लेकिन आप हमेशा की तरह कुछ कर सकता है:

:t ap . (id :: ((->) r a) -> ((->) r a)) 

या

:t \x y (id :: ...) (ap x y) 

दिलचस्प

Prelude Control.Monad> type Reader = (->) r 
Prelude Control.Monad> :t ap . (id :: Reader r a -> Reader r a) 
ap . (id :: Reader r a -> Reader r a) 
    :: Reader r (a -> b) -> (r -> a) -> r -> b 

Prelude Control.Monad> :t \x y -> (id :: Reader r a -> Reader r a) (ap x y) 
\x y -> (id :: Reader r a -> Reader r a) (ap x y) 
    :: (r -> a1 -> a) -> (r -> a1) -> Reader r a 
से अलग है

क्या GHC में पर्याय Reader r a

12

Lazersmoke के रूप में कहा एक टिप्पणी के रूप में आप TypeApplications विस्तार कि GHC 8.0 में पेश किया गया था के रूप में उपयोग कर सकते हैं पहचानता है।

GHCi में:

λ > :set -XTypeApplications 
λ > import Control.Monad 
λ > :t ap @((->) _) 
ap @((->) _) :: (t -> a -> b) -> (t -> a) -> t -> b 
संबंधित मुद्दे

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