类型变量 r 已超出其作用域
The type variable r has escaped its scope
我有一个拼图的类型同义词,定义如下:
type Cell = Int
type Board = Array Cell
type Puzzle = forall r.
{ board::Board
, meta::
{ metaData :: {|r}
, metaBoard :: (Array {|r})
}
}
我还包括了这样的想法,即策略采用拼图,returns 它包裹在三种状态之一中
type Strategy = Puzzle -> (Stateful Puzzle)
data Stateful a =
Advancing a
| Stable a
| Finished a
最后,我有一个函数可以让我们(稍微)回到 Either
的工作方式。我的想法是,最终我可以开始编写策略,直到达到完成状态。
advanceOrFinish :: (Stateful Puzzle) -> (Stateful Puzzle)
advanceOrFinish (Advancing puzzle)
| isSolvedOrInvalid puzzle.board = Finished puzzle
| otherwise = Advancing puzzle
advanceOrFinish (Stable puzzle)
| isSolvedOrInvalid puzzle.board = Finished puzzle
| otherwise = Advancing puzzle
advanceOrFinish (Finished puzzle) = Finished puzzle
问题是我遇到了这个错误:
The type variable r, bound at
src/SC.purs:23:15 - 29:4 (line 23, column 15 - line 29, column 4)
has escaped its scope, appearing in the type
{ board :: Array Int
, meta :: { metaBoard :: Array (Record r7)
, metaData :: Record r7
}
}
没有Stateful
(虽然没用)的相同功能没有这个问题。所以这很好:
advanceOrFinish :: Puzzle -> Puzzle
advanceOrFinish puzzle
| isSolvedOrInvalid puzzle.board = puzzle
| otherwise = puzzle
这个错误试图告诉我什么?
type Puzzle = forall r. ...
并不代表你想的那样。
如果你有一个变量:
p :: Puzzle
然后您想对该变量做一些事情,例如:
b = p.board
在那一刻,当您按名称引用 p
时,您可以选择类型 r
,然后变量 p
必须以某种方式“成为”那个类型,意思是 p.meta.metaData :: {|r}
.
每次访问变量p
时,都会发生这种情况。每次您选择某种类型 r
(并且每次都可能是不同的类型),并且每次字段 p.meta.metaData
都必须是该类型。
很明显,这不能合理地工作。很明显,这不是你的意思。
forall
的意思是“我将为所有 类型工作 ”——这就是名字中的字面意思。消费者选择哪种类型,而不是实施者。
你的意思可能是要有一个带有类型参数的Puzzle
,这样任何创建Puzzle
实例的人都可以选择当时的类型,然后选择[=的实例24=] 将继续使用该类型。
这样做的语法是这样的:
type Puzzle r =
{ board::Board
, meta::
{ metaData :: {|r}
, metaBoard :: (Array {|r})
}
}
这里r
称为Puzzle
的“类型参数”。
然后,每当你提到Puzzle
时,你必须说出r
是什么,例如:
foo :: Puzzle (a :: Int) -> Int
foo p = p.meta.metaData.a
bar :: Puzzle (x :: String) -> Unit
bar _ = unit
如果您不关心它是什么,它也可以是通用的:
advanceOrFinish :: forall r. Puzzle r -> Puzzle r
advanceOrFinish puzzle
| isSolvedOrInvalid puzzle.board = puzzle
| otherwise = puzzle
我有一个拼图的类型同义词,定义如下:
type Cell = Int
type Board = Array Cell
type Puzzle = forall r.
{ board::Board
, meta::
{ metaData :: {|r}
, metaBoard :: (Array {|r})
}
}
我还包括了这样的想法,即策略采用拼图,returns 它包裹在三种状态之一中
type Strategy = Puzzle -> (Stateful Puzzle)
data Stateful a =
Advancing a
| Stable a
| Finished a
最后,我有一个函数可以让我们(稍微)回到 Either
的工作方式。我的想法是,最终我可以开始编写策略,直到达到完成状态。
advanceOrFinish :: (Stateful Puzzle) -> (Stateful Puzzle)
advanceOrFinish (Advancing puzzle)
| isSolvedOrInvalid puzzle.board = Finished puzzle
| otherwise = Advancing puzzle
advanceOrFinish (Stable puzzle)
| isSolvedOrInvalid puzzle.board = Finished puzzle
| otherwise = Advancing puzzle
advanceOrFinish (Finished puzzle) = Finished puzzle
问题是我遇到了这个错误:
The type variable r, bound at
src/SC.purs:23:15 - 29:4 (line 23, column 15 - line 29, column 4)
has escaped its scope, appearing in the type
{ board :: Array Int
, meta :: { metaBoard :: Array (Record r7)
, metaData :: Record r7
}
}
没有Stateful
(虽然没用)的相同功能没有这个问题。所以这很好:
advanceOrFinish :: Puzzle -> Puzzle
advanceOrFinish puzzle
| isSolvedOrInvalid puzzle.board = puzzle
| otherwise = puzzle
这个错误试图告诉我什么?
type Puzzle = forall r. ...
并不代表你想的那样。
如果你有一个变量:
p :: Puzzle
然后您想对该变量做一些事情,例如:
b = p.board
在那一刻,当您按名称引用 p
时,您可以选择类型 r
,然后变量 p
必须以某种方式“成为”那个类型,意思是 p.meta.metaData :: {|r}
.
每次访问变量p
时,都会发生这种情况。每次您选择某种类型 r
(并且每次都可能是不同的类型),并且每次字段 p.meta.metaData
都必须是该类型。
很明显,这不能合理地工作。很明显,这不是你的意思。
forall
的意思是“我将为所有 类型工作 ”——这就是名字中的字面意思。消费者选择哪种类型,而不是实施者。
你的意思可能是要有一个带有类型参数的Puzzle
,这样任何创建Puzzle
实例的人都可以选择当时的类型,然后选择[=的实例24=] 将继续使用该类型。
这样做的语法是这样的:
type Puzzle r =
{ board::Board
, meta::
{ metaData :: {|r}
, metaBoard :: (Array {|r})
}
}
这里r
称为Puzzle
的“类型参数”。
然后,每当你提到Puzzle
时,你必须说出r
是什么,例如:
foo :: Puzzle (a :: Int) -> Int
foo p = p.meta.metaData.a
bar :: Puzzle (x :: String) -> Unit
bar _ = unit
如果您不关心它是什么,它也可以是通用的:
advanceOrFinish :: forall r. Puzzle r -> Puzzle r
advanceOrFinish puzzle
| isSolvedOrInvalid puzzle.board = puzzle
| otherwise = puzzle