۱۶ - ۱۶فانکتور هر نوع‌داده یکتاست

در هسکل، نمونه‌های ‏‎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‎‏ با رفتارِ متفاوت استفاده شده باشه.