'Nat'

2016-11-21 5 views
6

के साथ दयालु '*' से मेल नहीं खा रहा था, मैं एक ऐसा प्रकार बनाने की कोशिश कर रहा हूं जो गारंटी देता है कि स्ट्रिंग एन अक्षरों से कम है।'Nat'

src/Simple/Reporting/Metro2/TextMax.hs:18:50: error: 
• Couldn't match kind ‘*’ with ‘Nat’ 
    When matching the kind of ‘Proxy’ 
• In the first argument of ‘natVal’, namely ‘(Proxy :: Proxy n)’ 
    In the second argument of ‘($)’, namely ‘natVal (Proxy :: Proxy n)’ 
    In the second argument of ‘(<=)’, namely 
    ‘(fromIntegral $ natVal (Proxy :: Proxy n))’ 

मैं यह त्रुटि समझ में नहीं आता:

{-# LANGUAGE KindSignatures #-} 
{-# LANGUAGE OverloadedStrings #-} 
{-# LANGUAGE ScopedTypeVariables #-} 
{-# LANGUAGE DataKinds #-} 

import GHC.TypeLits (Symbol, Nat, KnownNat, natVal, KnownSymbol, symbolVal) 
import Data.Text (Text) 
import qualified Data.Text as Text 
import Data.Proxy (Proxy(..)) 

data TextMax (n :: Nat) = TextMax Text 
    deriving (Show) 

textMax :: KnownNat n => Text -> Maybe (TextMax n) 
textMax t 
    | Text.length t <= (fromIntegral $ natVal (Proxy :: Proxy n)) = Just (TextMax t) 
    | otherwise = Nothing 

यह त्रुटि देता है। यह क्यों काम नहीं करता है? I've used almost this exact same code to get the natVal of n in other places and it works

क्या ऐसा करने का कोई बेहतर तरीका है?

+1

साइड टिप्पणी: चालू करके ' पॉलीकिंड्स एक्सटेंशन, पीएचसी पॉली-टाइपेड 'प्रॉक्सी' के विचार के साथ अधिक उदार है और त्रुटि संदेश अलग हो जाता है और यह बहुत स्पष्ट बनाता है कि यह एक विशिष्ट 'स्कोप्ड टाइप टाइपरीबल्स' मुद्दा है। – gallais

उत्तर

7

आप textMax के हस्ताक्षर में स्पष्ट forall की जरूरत है, ताकि में ScopedTypeVariables किक और Proxy n एनोटेशन में nKnownNat n बाधा में एक ही n हो जाता है:

textMax :: forall n. KnownNat n => Text -> Maybe (TextMax n) 
textMax t 
    | Text.length t <= (fromIntegral $ natVal (Proxy :: Proxy n)) = Just (TextMax t) 
    | otherwise = Nothing 
संबंधित मुद्दे