【发布时间】:2021-05-04 13:56:46
【问题描述】:
GHC 为什么不为KO 派生Applicative?
#!/usr/bin/env stack
-- stack --resolver lts-17.10 script
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype KO a = KO a deriving (Functor, Applicative) -- doesn't derive Applicative
newtype OK f a = OK (f a) deriving (Functor, Applicative) -- that's ok
main :: IO ()
main = print "hello"
• 无法创建“Applicative KO”的派生实例 (即使使用狡猾的 GeneralizedNewtypeDeriving): 无法充分减少表示类型 • 在“KO”类型检查的新类型声明中
【问题讨论】:
-
如果你
:i Applicative你会看到这个:type Applicative :: (* -> *) -> Constraint- 所以如果类型是* -> *则类型可以是适用的(container 是适用的 - 比如[]或Maybe- 不是[a],Maybe a) - 这就是它不起作用的原因 - 你的 newtype 是 any 类型的包装器 - 如果你要为 @ 创建一个实例987654331@ 你会做Applicative f => instance Applicative (OK f)(Ok f : * -> *) - 尝试自己为KO编写一个实例 - 有一个(基本上是Identity- 查一下) - 但这不是你对新类型的期望包装器 -
如果
Identity行为是您想要的,您可以使用DerivingVia并说newtype KO a = KO a deriving (Functor, Applicative) via Identity -
deriving via更规律,更少惊喜 -
@Carsten, fwiw,
:i Functor也显示type Functor :: (* -> *) -> Constraint。那么为什么Functor没有提出同样的问题呢? -
@Enlico
Functor不会造成同样的问题,因为它使用了不同的实例生成方法。我的回答有一些细节和完整文档的链接。
标签: haskell