[英]Haskell assert that a type will match another
I need to let GHC know that the value being use inside of a type will be the same as a functions inputs. 我需要让GHC知道在一个类型中使用的值将与函数输入相同。
Config is defined as : 配置定义为:
data Config = forall p s . (PortIn p, SysState s, Show p, Show s) =>
Config { input :: p
, startSt :: s
}
Its class is: 它的类是:
class Show t => Transition t where
runOneTest :: forall st pin . (SysState st, PortIn pin)
=> t
-> (st -> Signal pin -> Signal st)
-> Signal TestResult
The instance is: 实例是:
instance Transition Config where
runOneTest = runOneTest'
runOneTest' :: forall st pin . (SysState st, PortIn pin)
=> Config
-> (st -> Signal pin -> Signal st)
-> Signal TestResult
runOneTest' config@Config{..} topEntity' = TestResult config <$> result
where
result = topEntity' startingState inputSignal
startingState = startSt
inputSignal = signal input
I am getting the errors: 我收到错误:
Couldn't match expected type `st' with actual type `s'
`s' is a rigid type variable bound by
a pattern with constructor
Config :: forall p s.
(PortIn p, SysState s, Show p, Show s) =>
p -> s -> Config,
in an equation for runOneTest'
at ConvertedClashExamples\TestProc.hs:61:20
`st' is a rigid type variable bound by
the type signature for
runOneTest' :: (SysState st, PortIn pin) =>
Config -> (st -> Signal pin -> Signal st) -> Signal TestResult
at ConvertedClashExamples\TestProc.hs:57:23
Relevant bindings include
result :: Signal st (bound at ConvertedClashExamples\TestProc.hs:63:5)
startingState :: s (bound at ConvertedClashExamples\TestProc.hs:64:5)
topEntity' :: st -> Signal pin -> Signal st (bound at ConvertedClashExamples\TestProc.hs:61:31)
startSt :: s (bound at ConvertedClashExamples\TestProc.hs:61:20)
runOneTest' :: Config
-> (st -> Signal pin -> Signal st) -> Signal TestResult
(bound at ConvertedClashExamples\TestProc.hs:61:1)
In the first argument of topEntity', namely `startingState'
In the expression: topEntity' startingState inputSignal
What I think the problem is: GHC has no way of knowing that the startSt and input are going to be compatible with the topEntity function I will be passing in. It just knows that they use some of the same classes. 我认为问题是: GHC无法知道startSt和input将与我将传入的topEntity函数兼容。它只知道它们使用了一些相同的类。
Your analysis is right on the spot: the caller can pass a Config
value which carries different types of those required by topEntity'
. 您的分析是正确的:调用者可以传递一个
Config
值,该值包含topEntity'
所需的不同类型。
One option is to avoid the existential Config
type and turn it into an explicit one 一种选择是避免存在的
Config
类型并将其转换为显式类型
data Config p s = ...
runOneTest' :: forall st pin . (SysState st, PortIn pin)
=> Config pin st
-> (st -> Signal pin -> Signal st)
-> Signal TestResult
...
Another option is to perform a runtime type check using Data.Typeable
. 另一种选择是使用
Data.Typeable
执行运行时类型检查。 Something like: 就像是:
import Data.Typeable
data Config = forall p s . (PortIn p, SysState s, Show p, Show s, Typeable s) =>
Config { input :: p
, startSt :: s
}
runOneTest' :: forall st pin . (SysState st, PortIn pin)
=> Config
-> (st -> Signal pin -> Signal st)
-> Signal TestResult
runOneTest' config@Config{..} topEntity' = TestResult config <$> result
where
result = topEntity' startingState inputSignal
startingState = startSt
inputSignal = signal input2
input2 = case cast input :: st of
Just i -> i
Nothing -> error "wrong runtime type!"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.