0 से 5 मान वाली सूची का प्रतिनिधित्व करने के लिए टाइप करें


14

मेरे पास एक व्यायाम है जहां मुझे 0 से 5 मानों के साथ सूची का प्रतिनिधित्व करने के लिए एक प्रकार को परिभाषित करना है। पहले मुझे लगा कि मैं इसे इस तरह पुन: हल कर सकता हूं:

data List a = Nil | Content a (List a)

लेकिन मुझे नहीं लगता कि यह सही तरीका है। क्या आप मुझे विचार का भोजन दे सकते हैं।

जवाबों:


12

मैं आपके लिए आपके व्यायाम का जवाब नहीं दूंगा - अभ्यास के लिए, इसका जवाब खुद पता लगाना बेहतर है - लेकिन यहां एक संकेत है जो आपको उत्तर की ओर ले जाना चाहिए: आप एक सूची को 0 से 2 तत्वों के रूप में परिभाषित कर सकते हैं

data List a = None | One a | Two a a

अब, इस बारे में सोचें कि आप इसे पांच तत्वों तक कैसे बढ़ा सकते हैं।


10

खैर, एक पुनरावर्ती समाधान निश्चित रूप से हास्केल में सामान्य और वास्तव में अच्छी बात है, लेकिन तत्वों की संख्या को सीमित करने के लिए यह थोड़ा मुश्किल है। इसलिए, समस्या के एक सरल समाधान के लिए, पहले ब्रैड द्वारा दिए गए बेवकूफ-लेकिन-काम करने वाले पर विचार करें।

पुनरावर्ती समाधान के साथ, चाल पुनरावृत्ति के नीचे "काउंटर" चर को पारित करने के लिए है, और तब अधिकतम अनुमति मिलने पर अधिक तत्वों को अक्षम करने को अक्षम करें। यह GADT के साथ अच्छी तरह से किया जा सकता है:

{-# LANGUAGE GADTs, DataKinds, KindSignatures, TypeInType, StandaloneDeriving #-}

import Data.Kind
import GHC.TypeLits

infixr 5 :#
data ListMax :: Nat -> Type -> Type where
  Nil :: ListMax n a
  (:#) :: a -> ListMax n a -> ListMax (n+1) a

deriving instance (Show a) => Show (ListMax n a)

फिर

*Main> 0:#1:#2:#Nil :: ListMax 5 Int
0 :# (1 :# (2 :# Nil))

*Main> 0:#1:#2:#3:#4:#5:#6:#Nil :: ListMax 5 Int

<interactive>:13:16: error:
     Couldn't match type 1 with 0
      Expected type: ListMax 0 Int
        Actual type: ListMax (0 + 1) Int
     In the second argument of ‘(:#)’, namely 5 :# 6 :# Nil
      In the second argument of ‘(:#)’, namely 4 :# 5 :# 6 :# Nil
      In the second argument of ‘(:#)’, namely 3 :# 4 :# 5 :# 6 :# Nil

बहुत बहुत धन्यवाद। क्योंकि यह एक शुरुआती अभ्यास है, मुझे लगता है कि यह आसान तरीका है। लेकिन मैं आपके दृष्टिकोण के बारे में भी सोचूंगा।
महापर्व

7

पूर्णता के लिए, मुझे एक "बदसूरत" वैकल्पिक दृष्टिकोण जोड़ना चाहिए, जो कि हालांकि बुनियादी है।

स्मरण करो कि Maybe aएक प्रकार जिसका मान रूप Nothingया Just xकुछ के लिए है x :: a

इसलिए, ऊपर दिए गए मूल्यों को फिर से परिभाषित करके, हम Maybe aएक "प्रतिबंधित सूची प्रकार" के रूप में मान सकते हैं, जहां सूचियों में शून्य या एक तत्व हो सकता है।

अब, (a, Maybe a)बस एक और तत्व जोड़ता है, इसलिए यह एक "सूची प्रकार" है जहां सूचियों में एक ( (x1, Nothing)) या दो ( (x1, Just x2)) तत्व हो सकते हैं।

इसलिए, Maybe (a, Maybe a)एक "सूची प्रकार" है जहां सूचियों में शून्य ( Nothing), एक ( Just (x1, Nothing)), या दो ( (Just (x1, Just x2)) तत्व हो सकते हैं।

अब आपको समझना चाहिए कि आगे कैसे बढ़ना है। मुझे फिर से तनाव दें कि यह उपयोग करने के लिए एक सुविधाजनक समाधान नहीं है, लेकिन यह (आईएमओ) वैसे भी इसे समझने के लिए एक अच्छा व्यायाम है।


हास्केल की कुछ उन्नत सुविधाओं का उपयोग करके, हम एक प्रकार के परिवार का उपयोग करके उपरोक्त को सामान्य कर सकते हैं:

type family List (n :: Nat) (a :: Type) :: Type where
    List 0 a = ()
    List n a = Maybe (a, List (n-1) a)

यह उत्तर अधिकतम-लंबाई n की शायद-आधारित सूची के प्रकार परिवार के साथ बढ़ाया जा सकता है ।
लेफ्टनैबाउटआउट

@leftaroundabout ने किया। यह एक शुरुआत के लिए बहुत अधिक हो सकता है, लेकिन मैंने इसे वैसे भी जोड़ा।
ची

में सबसे अधिक तीन aएस Either () (a, Either () (a, Either () (a, Either () ())))... दिलचस्प प्रकार बीजगणित foldr (.) id (replicate 3 $ ([0] ++) . liftA2 (+) [1]) $ [0] == [0,1,2,3],।
विल नेस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.