说我有一些foo :: Maybe Int,我想绑定它,例如bar :: Int -> MaybeT (Writer String) Int,这是什么惯用的方法呢?
我可以定义自己的liftMaybe函数,然后使用它,如:
let liftMaybe = maybe (fail "Nothing") return in liftMaybe foo >>= bar
Run Code Online (Sandbox Code Playgroud)
但是,是否有更惯用(或至少简洁)的方式呢?
我正在努力掌握GADTs,并且我已经查看了GHC手册中的GADT示例.据我所知,有可能做同样的事情MultiParamTypeClasses:
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies,
FlexibleInstances, UndecidableInstances #-}
class IsTerm a b | a -> b where
eval :: a -> b
data IntTerm = Lit Int
| Succ IntTerm
data BoolTerm = IsZero IntTerm
data If p a = If p a a
data Pair a b = Pair a b
instance IsTerm IntTerm Int where
eval (Lit i) = i
eval (Succ t) = 1 + eval t
instance IsTerm BoolTerm Bool …Run Code Online (Sandbox Code Playgroud) 让我们做出以下假设:
我如何找出该例外的类型?
最小的例子:
main = error "foo"
Run Code Online (Sandbox Code Playgroud)
(这是当然的ErrorCall,但你无法从错误信息中得知.)
Wen使用函数依赖,我经常达到Coverage条件.可以用它抬起UndecidableInstances,但我通常会试图远离那个延伸.
这是一个有点人为的例子,没有UndecidableInstances:
{-# Language MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-}
data Result = Result String
deriving (Eq, Show)
data Arguments a b = Arguments a b
class Applyable a b | a -> b where
apply :: a -> b -> Result
instance Applyable (Arguments a b) (a -> b -> Result) where
(Arguments a b) `apply` f = f a b
Run Code Online (Sandbox Code Playgroud)
当我使结果类型更通用时,Coverage条件失败(因此需要UndecidableInstances):
{-# Language MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, UndecidableInstances #-}
data Result a = …Run Code Online (Sandbox Code Playgroud) 启用时PolyKinds,以前有效的类型签名可能会变为无效.
以下代码编译时没有PolyKinds.
{-# LANGUAGE KindSignatures #-}
import GHC.Generics
foo :: Constructor c => t c (f :: * -> *) a -> [Char]
foo = conName
Run Code Online (Sandbox Code Playgroud)
当我启用PolyKinds它无法编译.
Kind incompatibility when matching types:
t0 :: * -> (* -> *) -> * -> *
t :: * -> (* -> *) -> k -> *
Expected type: t c f a -> [Char]
Actual type: t0 c f a0 -> [Char]
Relevant bindings include
foo …Run Code Online (Sandbox Code Playgroud)