簡體   English   中英

Functor的實例

[英]Instance of a Functor

我有以下類型newtype Arr2 e1 e2 a = Arr2 { getArr2 :: e1 -> e2 -> a } 我必須為它編寫Functor實例,但我真的不明白我的嘗試方式

instance Functor (Arr2 e1 e2) where
  fmap g (Arr2 a) = Arr2 (g a)

instance Functor (Arr2 e1 e2) where
  fmap g = g . getArr2

這實際上導致了類型

(a -> b) -> Arr2 e1 e2 a -> b

而不是期望

(a -> b) -> Arr2 e1 e2 a -> Arr2 e1 e2 b

所以,請幫助我

Functor類具有以下定義:

class Functor f where:
    fmap :: (a -> b) -> f a -> f b
    (<$) :: a -> f b -> f a

(<$)有一個默認實現: (<$) = fmap . const (<$) = fmap . const工作得很好。

這意味着如果我們輸入一個函數( g :: a -> b )作為第一個參數,並且一個Arr2產生一個a ,我們必須生成一個Arr2 ,如果它被應用,則在箭頭的結果上調用g

因此,您的Arr2fmap定義是:

instance Functor (Arr2 e1 e2) where
  fmap g (Arr2 a) = Arr2 (\x y -> g (a x y))

或者更優雅:

instance Functor (Arr2 e1 e2) where
  fmap g (Arr2 a) = Arr2 (\x -> g . (a x))

或更優雅的版本 - 由@Alec評論:

instance Functor (Arr2 e1 e2) where
  fmap g (Arr2 a) = Arr2 ((g .) . a)

(你可以轉換使用表達式來pointfree那些該工具

Willem Van Onsem提供的答案非常好,我只想建議使用一種語言擴展,可以輕松地為newtypes創建Functor實例: DeriveFunctor

在模塊的頂部,您可以添加:

{-# LANGUAGE DeriveFunctor #-}

然后,您可以自動派生您的Functor實例:

newtype Arr2 e1 e2 a = Arr2 { getArr2 :: e1 -> e2 -> a } deriving Functor

以下是我如何在GHCi中找到此實例的fmap類型:

λ > :set -XDeriveFunctor
λ > newtype Arr2 e1 e2 a = Arr2 { getArr2 :: e1 -> e2 -> a } deriving Functor
λ > :set -XTypeApplications 
λ > :t fmap @(Arr2 _ _)
fmap @(Arr2 _ _) :: (a -> b) -> Arr2 t t1 a -> Arr2 t t1 b

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM