我已经提升了 typeNat = Suc Nat | Zero
并且我想创建一个 typeclass class C (a :: Nat) b
。有没有办法说服 GHCinstance C Zero b
并instance C (Seq x) b
涵盖所有情况,因此每当我使用类的方法时,我都不需要显式声明C
为约束。这是一些代码:
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE IncoherentInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
-- Some of these may not be necessary for the particular snippet.
data Nat = Zero | Suc Nat
-- TypeApplications, I know. I am traditional.
data NProxy :: Nat -> * where
NProxy :: NProxy n
class C (a :: Nat) b where
f :: NProxy a -> b -> Maybe b
instance C Zero b where
f _ _ = Nothing
instance C (Suc a) b where
f _ = Just
-- instance C n b where
-- f = error "This should not have been reached using GetNum."
class C1 a where
f1 :: a -> Maybe a
instance C1 a where
f1 = Just
type family GetNum a :: Nat where
GetNum Char = (Suc Zero)
GetNum Int = Suc (Suc Zero)
GetNum [x] = Suc (GetNum x)
GetNum a = Suc Zero
-- Error:
-- • No instance for (C (GetNum a) a) arising from a use of ‘f’
-- • In the expression: f (NProxy :: NProxy (GetNum a)) x
-- In an equation for ‘noGreet’:
-- noGreet x = f (NProxy :: NProxy (GetNum a)) x
noGreet :: forall a . a -> Maybe a
noGreet x = f (NProxy :: NProxy (GetNum a)) x
-- This one works fine though.
dumb :: a -> Maybe a
dumb = f1
编辑:一个相关的问题是,考虑到注释掉的实例 if C
,为什么当我noGreet "hi"
对 repl 说我得到一个异常而不是Just "hi"
。