[英]What would be the Functor instance for the following type: newtype F2 x a = F2 ((a -> x) -> a)
[英]Functor instance for (newtype Mu f = InF {outF :: f (Mu f)})
這讓我很難過。 如何為newtype Mu f = InF {outF :: f (Mu f)}
編寫 Functor 實例
你不能。 為了為某些c
定義實例Functor c
, c
必須是* -> *
類型。 所以在你的情況下, Mu
應該是那種,這意味着它的論點f
必須是那種*
。 但顯然情況並非如此,因為您將f
應用於其他事物(對Mu f
)。
更簡單地說,如果Mu
是一個仿函數,則可以對任何f
類型的Mu f
值使用fmap
。 但這將允許您將類型參數更改為任何其他類型,例如,通過將函數fmap (const (0 :: Int))
應用於任何Mu f
值,它必須返回一個Mu Int
值。 但是您不能形成這樣的值,因為該值的outF
將具有沒有意義的Int (Mu Int)
類型。
redneb 很好地解釋了為什么Mu
不能成為常規Functor
但您可以為Mu
實現一種類似仿函數的映射操作
{-# LANGUAGE RankNTypes #-}
newtype Mu f = InF {outF :: f (Mu f)}
mumap :: Functor f => (forall a. f a -> g a) -> Mu f -> Mu g
mumap f (InF m) = InF $ f $ fmap (mumap f) m
雖然我不確定它對你的情況有多大用處。 :)
與 user2297560 不同的對Mu
的輕微改寫足以承認 Mu 的 Functor 實例:
-- Natural transformations
type g ~> h = forall a. g a -> h a
class HFunctor f where
ffmap :: Functor g => (a -> b) -> f g a -> f g b
hfmap :: (Functor g, Functor h) => (g ~> h) -> (f g ~> f h)
newtype Mu f a = In { unIn :: f (Mu f) a }
instance HFunctor f => Functor (Mu f) where
fmap f (In r) = In (ffmap f r)
這個公式來自 Patricia 和 Neil 的論文Haskell Programming with Nested Types: A Principled Approach 。
正如 redneb 所描述的,仿函數實例必須具有* -> *
種類,這禁止Mu
成為仿函數,因為它的參數f
應用於f (Mu f)
中的參數。
這是所涉及的各種類型的細分。
首先,創建的新類型,在所有應用的參數之后,必須有種類*
。 所以:
Mu f
必須有種類*
。
其次, Mu f
被設置為等於的也必須具有相同的種類。 那是,
InF { outF :: f (Mu f) }
必須有種類*
。
第三, outF
是一個函數,因此必須返回一個完全實現的類型,無論是參數化的還是具體的,即類型*
。 f (Mu f)
是它的返回類型。 所以
f (Mu f)
必須有種類*
。
最后, f
是一種應用類型,因為它出現在f (Mu f)
中。 換句話說,它有一種f_argument_kind -> f_result_kind
用於某種f_argument_kind
和某種f_result_kind
。 此外, f (Mu f)
告訴我們f_argument_kind
和f_result_kind
的種類。 也就是說, f_argument_kind
匹配Mu f
的種類 ( *
), f_result_kind
匹配f (Mu f)
的種類 ( *
)。 所以
f
有種類* -> *
。
將其與已知類型的Mu f
( *
) 結合,我們得到類型構造函數的類型。
Mu
有種類(* -> *) -> *
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.