类型同义词导致类型错误

卡尔·马克伦(Karl Marklund)

作为我上一个问题的跟进,同时使用makeLenses,类约束和类型同义词,我想了解一个新的类型错误。

类型错误是由type S = (Num n) => State n以下示例中引入类型同义词引起的

{-# LANGUAGE TemplateHaskell #-}                                                                                                                              
{-# LANGUAGE RankNTypes #-}                                                                                                                                   

module Foo where                                                                                                                                              

import Control.Lens                                                                                                                                           

data State a = State { _a :: a                                                                                                                                
                     } deriving Show                                                                                                                          

makeLenses ''State -- Requires TemplateHaskell                                                                                                                

-- | Smart constructor enforcing class constraint on record field _a.                                                                                         
mkState :: (Num a) =>  a -> State a                                                                                                                           
mkState n = State {_a = n}                                                                                                                                    

doStuff1 :: Num a => State a -> State a                                                                                                                       
doStuff1 s = s & a %~ (*2)                                                                                                                                    

test1a = doStuff1 $ mkState  5   -- results in State {_a = 10.0}                                                                                              
test1b = doStuff1 $ mkState  5.5 -- results in State {_a = 11.0}                                                                                                                                                           

type S = (Num n) => State n -- Requires the RankNTypes extensions                                                                                             

doStuff2 :: S -> S                                                                                                                                            
doStuff2 s = s & a %~ (*2)                                                                                                                                    

test2a = doStuff2 $ mkState  5   -- Results in State {_a = 10.0}                                                                                              
--test2b = doStuff2 $ mkState  5.5 -- Type error.

如果我取消注释,则会test2b出现以下错误。

Could not deduce (Fractional n) arising from the literal `5.5'
from the context (Num n)
  bound by a type expected by the context: Num n => State n
  at Foo.hs:32:10-32
Possible fix:
  add (Fractional n) to the context of
    a type expected by the context: Num n => State n
In the first argument of `mkState', namely `5.5'
In the second argument of `($)', namely `mkState 5.5'
In the expression: doStuff2 $ mkState 5.5

我希望能够理解为什么引入的类型同义词会导致此错误,以及如何解读错误消息。

sepp2k

S -> S不等同于forall n. Num n => State n -> State n等同于(forall n. Num n => State n) -> (forall n. Num n => State n)前者意味着,对于所有数字类型n,我们可以传入aState n并取回a State n(对于同一类型n)。后者意味着我们传递可以State n用于所有数值类型的n东西,并取回可以State n适用于所有类型的东西n换句话说,参数和结果都是多态的。

这意味着您传入的参数必须具有type Num n => State n,而不是更具体的类型,例如State Int这是正确的5,具有类型Num n => n,但是没有5.5类型Fractional n => n

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

定义类型同义词(GHC)的类型同义词时出现奇怪的错误

找出类型同义词的类型

在haskell中查找类型同义词

让Haskell区分类型同义词

使用类型同义词定义实例

在类型声明映射中使用类型同义词

类型族作为类型同义词的参数

为什么关联的类型同义词不暗示约束

我的Haskell类型同义词有什么问题?

基于lambda / church布尔值的类型同义词

使用模板Haskell获取关联的类型同义词

如何在实例声明中使用类型同义词?

Java泛型和类型同义词

一个类中的多个类型同义词

使用特定的类定义类型同义词

如何为类型类名称创建同义词?

Purescript 将类视为循环类型同义词

Haskell术语:类型与数据类型的含义,它们是同义词吗?

模式同义词无法统一类型级别列表中的类型

由类型同义词中的函数依赖项绑定的“自由”类型变量

无法制作具有类型同义词的对象:类型

您为什么不能(完全)应用带有使用其他类型同义词的参数的类型同义词?

我可以轻松地将我的元组类型同义词设为Read的实例吗?

模式同义词能否在每个方向都有不同的类型签名,就像数字文字那样?

如何为F#中的各种角色定义int,float等的类型同义词?

Haskell中是否可能有健忘的类型同义词?

是否存在部分类型同义词实例的Haskell(GHC)扩展?

Data.Semigroup中的ArgMin和ArgMax类型同义词的目的是什么?

Haskell:实例中的非法类型同义词系列应用程序