2017-05-07 9 views
6

मैं निम्नलिखित लिख सकते हैं:की कमी बाधा

{-# LANGUAGE RankNTypes #-} 
{-# LANGUAGE FlexibleInstances #-} 
{-# LANGUAGE UndecidableInstances #-} 
{-# LANGUAGE ConstraintKinds #-} 

f :: Integral a => (forall b. Num b => b) -> a 
f = id 

और यह सब अच्छा है। संभावित रूप से जीएचसी Num से Integral प्राप्त कर सकता है, इसलिए सब ठीक है।

मैं थोड़ा चालबाज हो सकता है, अभी तक मैं अभी भी ठीक हूँ:

class Integral x => MyIntegral x 
instance Integral x => MyIntegral x 

class Num x => MyNum x 
instance Num x => MyNum x 

f' :: MyIntegral a => (forall b. MyNum b => b) -> a 
f' = id 

तो कहते हैं कि मैं इस सामान्यीकरण करने के लिए है, इसलिए की तरह चाहते हैं कर सकते हैं:

g :: c2 a => (forall b. c1 b => b) -> a 
g = id 

अब स्पष्ट रूप से यह थूक होगा डमी, क्योंकि जीएचसी से प्राप्त नहीं कर सकता है, क्योंकि c2 बाधित नहीं है।

g के प्रकार हस्ताक्षर में जोड़ने के लिए मुझे क्या कहना है कि " से आप c2 प्राप्त कर सकते हैं"?

+1

जब आप कहते हैं "एक्स से एक्स एक्स प्राप्त करें", तो मैं कहूंगा "एक्स से एक्स प्राप्त करें"। आपके पहले उदाहरण में, हमारे पास 'इंटीग्रल टी' का अर्थ है 'नम टी', और दूसरी तरफ नहीं। जीएचसी को पारित 'इंटीग्रल' से 'न्यूम' शब्द निकालना है। और इसी तरह अन्य मामलों के लिए आप नीचे उल्लेख करते हैं। – chi

उत्तर

7

constraints पैकेज इस समस्या का समाधान, टाइप प्रदान करता है अपने :- ("जरूरत पर जोर देता") के माध्यम से:

:

{-# LANGUAGE ConstraintKinds #-} 
{-# LANGUAGE GADTs #-} 
{-# LANGUAGE KindSignatures #-} 
{-# LANGUAGE RankNTypes #-} 
{-# LANGUAGE TypeOperators #-} 

import GHC.Exts 

data Dict :: Constraint -> * where 
    Dict :: a => Dict a 

newtype a :- b = Sub (a => Dict b) 
infixr 9 :- 

g, g' :: c2 a => c2 a :- c1 a -> (forall b. c1 b => b) -> a 
g (Sub Dict) x = x 

फिर, एक उचित गवाह में पास करके, हम मूल उदाहरण ठीक हो सकता है

integralImpliesNum :: Integral a :- Num a 
integralImpliesNum = Sub Dict 

f :: Integral a => (forall b. Num b => b) -> a 
f = g integralImpliesNum 

वास्तव में, इस g केवल \\ ऑपरेटर के एक से फ़्लिप किया और विशेष संस्करण है:

(\\) :: a => (b => r) -> (a :- b) -> r 
r \\ Sub Dict = r 
infixl 1 \\ 

g' = flip (\\) 

यदि आपके पास समय है, तो एडवर्ड Kmett की बात "Type Classes vs the World" यह सब कैसे काम करता है यह एक महान परिचय है।

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