简体   繁体   English

Haskell断言一个类型会匹配另一个类型

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM