2017-06-17 152 views
1

好日/夜大家! 我有型:如何寫地圖/ fmap模擬(a-> b) - > F m a - > F m b

data FixItem m a = KeepItem|SkipItem|FixItem (m (a -> a)) 
fixItem f = FixItem $ pure f 

,我想寫功能mapFix :: (a -> b) -> FixItem m a -> FixItem m b。當我嘗試:

mapFix f SkipItem = SkipItem -- good 
mapFix f KeepItem = fixItem f -- error "rigid type"!!! 
mapFix f (FixItem mf) = FixItem $ pure (.) <*> (pure f) <*> mf -- too! 

所以,我得到錯誤:

• Couldn't match type ‘b’ with ‘a’ 
     ‘b’ is a rigid type variable bound by 
     the type signature for: 
      mapFix :: forall (m :: * -> *) a b. 
        Applicative m => 
        (a -> b) -> FixItem m a -> FixItem m b 
     at src/test.hs:235:11 
     ‘a’ is a rigid type variable bound by 
     the type signature for: 
      mapFix :: forall (m :: * -> *) a b. 
        Applicative m => 
        (a -> b) -> FixItem m a -> FixItem m b 
     at src/test.hs:235:11 
     Expected type: b -> b 
     Actual type: a -> b 
    • In the first argument of ‘fixItem’, namely ‘f’ 
     In the expression: fixItem f 
     In an equation for ‘mapFix’: mapFix f KeepItem = fixItem f 
    • Relevant bindings include 
     f :: a -> b (bound at src/test.hs:236:8) 
     mapFix :: (a -> b) -> FixItem m a -> FixItem m b 
      (bound at src/test.hs:236:1) 

如何寫mapFix或實現函子實例這種類型(FixItem修復aa,不b,IE修復是a -> a ,而不是a -> b)?

回答

4

您不能爲您的數據類型實施Functor類型類。這是因爲你的一個構造函數中有 a -> a。當你有功能時,你應該更加小心。但簡而言之,您將逆變類型變量a鍵入,因此您無法在此類型變量上實現Functor

儘管您可以爲您的數據類型實施Invariant。因爲a協變逆變職位,您的數據類型是不變的函子。

可以幫助您:

Example of Invariant Functor?

What is a contravariant functor?

Some blog post

+0

我懷疑函子是不可能的,所以這是不是意味着'mapFix'功能是不可能的呢?順便說一句,當我改變類型爲'FixItem mab = FixItem(m(a - > b))| SkipItem | KeepItem'並嘗試實現Functor時,我再次得到有關正確類型'a'的錯誤... –

+0

嗯,我得到了它:在FixITem中,'純f'和'mf'組成'a - > b',而FixItem僅支持'a - > a'。所以,mapFix是不可能的。但是可以實現'FixITem m a b = FixITem(m(a - > b))| ...'Functor實例嗎? –

+0

啊,OK,完成:)'fmap f(FixItem mf)= FixItem $ pure(。)<*>(純f)<*> mf'。謝謝! –

相關問題