多態構造我有一個類型級列表L,並正嘗試寫一個多態MKL,可以使用如下:類型級列表
{-# LANGUAGE TypeOperators, PolyKinds, DataKinds, TypeFamilies,
UndecidableInstances, AllowAmbiguousTypes, TypeSynonymInstances,
FlexibleInstances, ScopedTypeVariables #-}
data T = Foo | Bar
deriving (Show, Eq)
data L (ts :: [T]) = L [T]
deriving (Show, Eq)
demo1 :: L '[Foo]
demo1 = mkL
demo2 :: L '[Foo, Bar]
demo2 = mkL
我demo1的輕鬆工作就夠了,但由於某種原因,遞歸案件正在擊敗我。
class MkL p where
mkL :: p
instance MkL (L '[]) where
mkL = L []
instance MkL (L '[Foo]) where
mkL = L [Foo]
instance MkL (L '[Bar]) where
mkL = L [Bar]
instance MkL (L (l1 ': l2 ': ls)) where
mkL =
let (L [l1]) = undefined -- FIXME
(L [l2]) = undefined
(L rest) = undefined
in L (l1 : l2 : rest)
如果我MKL更換FIXME,我得到:
No instance for (MkL (L t0)) arising from a use of ‘mkL’
The type variable ‘t0’ is ambiguous
Note: there are several potential instances:
instance MkL (L (l1 : l2 : ls)) -- Defined at Target.hs:19:10
instance MkL (L '['Bar]) -- Defined at Target.hs:17:10
instance MkL (L '['Foo]) -- Defined at Target.hs:15:10
...plus one other
In the expression: mkL
In a pattern binding: (L [l1]) = mkL
那麼,有沒有什麼辦法來實現這一點?
儘管您正在遞歸地定義mkL,並且您已經定義了基本案例,但您的最後一個實例缺少一個至關重要的元素,使得它當前完全無法遞歸!你如何使用Haskell來引入適當的MkL約束,從而讓遞歸啓動? – hao