gpt4 book ai didi

haskell - 在 Haskell 中,如何将类型类与该类型类的实例进行匹配?

转载 作者:行者123 更新时间:2023-12-04 23:16:15 25 4
gpt4 key购买 nike

我定义了以下类:

class Configuration c where
input :: (PortIn pin, Show pin) => c -> pin
startSt :: (SysState st, Show st) => c -> st

class (Eq pin, Show pin) => PortIn pin

class (Eq st, Show st) => SysState st

以下类型和实例:
--inputs
data PIn = PIn { _clk :: Bit
, _reset :: Bool
, _start :: Bool
, _stop :: Bool
} deriving (Eq)
instance PortIn PIn
instance Show PIn where
show PIn {..} =
"PIn\n\t _clk = " P.++ show _clk
P.++ "\n\t _reset = " P.++ show _reset
P.++ "\n\t _start = " P.++ show _start
P.++ "\n\t _stop = " P.++ show _stop

--Outputs and state data
data St = St { _cnt_en :: Bool
, _count_us :: BitVector 4
, _stop_d1 :: Bool
, _stop_d2 :: Bool
, _count :: BitVector 4
} deriving (Eq)

instance SysState St
instance Show St where
show St {..} =
"St\n\t _cnt_en = " P.++ show _cnt_en

P.++ "\n\t _count_us = " P.++ show _count_us
P.++ "\n\t _stop_d1 = " P.++ show _stop_d1
P.++ "\n\t _stop_d2 = " P.++ show _stop_d2
P.++ "\n\t _count = " P.++ show _count

为什么我无法在此处创建 Configuration 实例:
data Config = Config { input'  :: PIn
, startSt' :: St
} deriving (Eq)

instance Show Config where
show Config {..} =
"Config:\n input = " P.++ show input'
P.++ "\n startSt = " P.++ show startSt'

instance Configuration Config where
input = input'
startSt = startSt'

我收到以下错误:
Couldn't match type ‘pin’ with ‘PIn’
‘pin’ is a rigid type variable bound by
the type signature for
input :: (PortIn pin, Show pin) => Config -> pin
at Clks_n_regs_4.hs:101:3
Expected type: Config -> pin
Actual type: Config -> PIn
Relevant bindings include
input :: Config -> pin (bound at Clks_n_regs_4.hs:101:3)
In the expression: input'
In an equation for ‘input’: input = input'

我认为我可以使用 input' ,因为它会在 pin 的实例中产生一个 PIn。

我在某处有误解,希望有人能解释我所缺少的。

最佳答案

要了解为什么您的代码不进行类型检查,请参阅:existential vs. universally quantified types .为了使这项工作,一种可能性是使用 Functional Dependencies .那么你的类型类将是:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}

class (PortIn pin, Show pin, SysState st, Show st) => Configuration c pin st
| c -> pin, c -> st where
input :: c -> pin
startSt :: c -> st

并且实例定义将是:
instance Configuration Config PIn St where
input = input'
startSt = startSt'

这将使您的代码类型检查,尽管可能不是您所追求的。

另一个方向是使用 existential types .在这种情况下:
{-# LANGUAGE ExistentialQuantification #-}

data PortInShow = forall a . (PortIn a, Show a) => PortInShow a
data SysStateShow = forall a . (SysState a, Show a) => SysStateShow a

class Configuration c where
input :: c -> PortInShow
startSt :: c -> SysStateShow

instance Configuration Config where
input = PortInShow . input'
startSt = SysStateShow . startSt'

关于haskell - 在 Haskell 中,如何将类型类与该类型类的实例进行匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41412958/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com