我有一个非常简单的代码片段:
{-# LANGUAGE LinearTypes #-}
module Lib where
data Peer st = Peer { data :: String } deriving Show
data Idle
data Busy
sendToPeer :: Peer Idle %1-> Int -> IO (Peer Busy)
sendToPeer c n = case c of Peer d -> pure $ Peer d
我正在使用resolver: ghc-9.0.1
。
根据文档:
一个函数 f 是线性的,如果:当其结果恰好被消耗一次时,它的参数也恰好被消耗一次。直觉上,这意味着在 f 的定义的每个分支中,其参数 x 必须恰好使用一次。这可以通过以下方式实现:
- 返回未修改的 x
- 将 x 传递给线性函数
- 对 x 进行模式匹配,并以相同方式使用每个参数仅一次。
- 作为函数调用,并以相同方式使用结果仅一次。
而我的 sendToPeer
函数正是这样做的——在 c
上进行模式匹配,其参数 d
仅在 Peer d
中被使用一次,这是线性的:
默认情况下,代数数据类型中的所有字段都是线性的(即使没有打开 -XLinearTypes)。
但是我收到了一个错误:
• Couldn't match type ‘'Many’ with ‘'One’
arising from multiplicity of ‘c’
• In an equation for ‘sendToPeer’:
sendToPeer c n = case c of { Peer d -> pure $ Peer d }
|
11 | sendToPeer c n =
| ^
没有 pure
:
sendToPeer :: Peer Idle %1-> Int -> Peer Busy
sendToPeer c n = case c of Peer d -> Peer d
但是错误依旧存在。
pure
并且不会返回Peer Busy
,而是返回IO (Peer Busy)
- 错误相同。 - RandomB