我正在嘗試為 datatype 定義一個函子實體Terms,它看起來像:
data Terms a = Var a | App (Terms a) (Terms a) | Abs (Terms (Maybe a))
| Const Integer | Add (Terms a) (Terms a)
| IfZero (Terms a) (Terms a) (Terms a) | Y
deriving (Show,Eq)
但是,我在處理Abs.
我的定義目前看起來像這樣:
instance Functor Terms where
fmap f (Var x) = Var (f x)
fmap f (App t1 t2) = App (fmap f t1) (fmap f t2)
fmap f (Abs t) = Abs (fmap f t)
fmap f (Const n) = Const n
fmap f (Add t1 t2) = Add (fmap f t1) (fmap f t2)
fmap f (IfZero t1 t2 t3) = IfZero (fmap f t1) (fmap f t2) (fmap f t3)
fmap f Y = Y
我已經嘗試了幾種不同的方法來繞過 theMaybe以便將該函式應用于該術語,但是我還不太明白。我知道Maybe型別本身就是一個函子,這意味著它fmap應該自動處理它,我只是不確定如何解決它不能作為Maybe.
uj5u.com熱心網友回復:
錯誤來自這一行:
fmap f (Abs t) = Abs (fmap f t)
Abs包含 a Maybe (Term a),并且您想要獲取 a Maybe (Term b),但是f型別為a -> b。因此,當您嘗試使用fmap它時,您正在將 a 傳遞Term a給一個接受a. 顯然這行不通。相反,創建一個Term a -> Term bwith fmap f,然后fmap那個(創建一個 double fmap):
fmap f (Abs t) = Abs (fmap (fmap f) t)
uj5u.com熱心網友回復:
YesMaybe本身就是一個函子,因此它有自己的 fmap:
fmap f (Abs t) = Abs (fmap? (fmap? f) t)
-- t :: Terms (Maybe a)
-- f :: a -> b
-- fmap? f :: Maybe a -> Maybe b
-- fmap? (fmap? f) :: Terms (Maybe a) -> Terms (Maybe b)
下標索引不是代碼的一部分,僅用于說明目的。或者我們可以TypeApplications用來區分它們:
*Main> :set -XTypeApplications
*Main> fmap @Maybe ( 1) $ Just 7
Just 8
*Main> fmap @Terms ( 1) $ Abs $ Var $ Just 8
Abs (Var (Just 9))
但是這里不需要它們,并且普通fmaps 也可以作業——根據引數的型別,Haskell 知道應用哪個:
*Main> fmap ( 1) $ Just 7
Just 8
*Main> fmap ( 1) $ Abs $ Var $ Just 8
Abs (Var (Just 9))
uj5u.com熱心網友回復:
另一種選擇是通過將組合結構轉換Terms (Maybe a)為Scoped Terms a. 您的Functor Terms實體保持不變。
相反,組合發生在 中Functor (Scoped exp),通過exp和Maybe( Compose exp Maybe)的組合推匯出來。這就是fmap = fmap . fmap派生的方式(模新型別包裝)。
{-# Language DerivingVia #-}
type Scoped :: (Type -> Type) -> (Type -> Type)
newtype Scoped exp a = Scoped (exp (Maybe a))
deriving (Functor, Applicative, Alternative, Foldable, Arbitrary1, ..)
via Compose exp Maybe
這是 Edward Kmett 的系結庫所采用的方法。
Bound.Scope.Scope:
type Scope :: Type -> (Type -> Type) -> (Type -> Type)
newtype Scope bound exp free = Scope (exp (Var bound (exp free)))
Bound.Scope.Simple.Scope:
type Scope :: Type -> (Type -> Type) -> (Type -> Type)
newtype Scope bound exp free = Scope (exp (Var bound free))
其中Var=Either:
type Var :: Type -> Type -> Type
data Var bound free
= B bound -- this is a bound variable
| F free -- this is a free variable
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/363870.html
上一篇:使用遞回修改串列
