ابتدای محتوای صفحه
۱۶ - ۱۶فانکتور هر نوعداده یکتاست
در هسکل، نمونههای Functor
برای یک نوعداده یکتااند. دیدیم که چنین چیزی برای Monoid
صادق نبود؛ که البته با newtype
، قاعدهی یکتا بودنِ جفتِ نمونه و تایپ رو حفظ میکردیم. ولی نمونههای Functor
یکتااند، هم به خاطرِ پارامتریسیته، و هم به خاطرِ اینکه آرگومانهای تایپ به همون ترتیبی اعمال میشن که در تعریفِ نوعداده مشخص شده. در یه زبان فرضیِ غیرهسکل، کُدِ زیر شاید کار کنه:
data Tuple a b =
Tuple a b
deriving (Eq, Show)
-- این در هسکل غیرممکنه
instance Functor (Tuple ? b) where
fmap f (Tuple a b) = Tuple (f a) b
اساساً از دو راه میشه چنین کاری کرد. یکی جابجا کردنِ آرگومانهای نوعساز ِه؛ یکی هم اینه که با newtype
یه نوعداده ِ Flip
درست کنیم:
{-# LANGUAGE FlexibleInstances #-}
module FlipFunctor where
data Tuple a b =
Tuple a b
deriving (Eq, Show)
newtype Flip f a b =
Flip (f b a)
deriving (Eq, Show)
-- .هرچقدر مسخره، اما این کار میکنه
instance Functor (Flip Tuple a) where
fmap f (Flip (Tuple a b)) =
Flip $ Tuple (f a) b
Prelude> fmap (+1) (Flip (Tuple 1 "blah"))
Flip (Tuple 2 "blah")
با این حال Flip Tuple a b
یه تایپ مجزا از Tuple a b
ِه، حتی اگه فقط برای تأمینِ یه نمونه ِ Functor
با رفتارِ متفاوت استفاده شده باشه.