我首先尝试从问题中解释代码中发生了什么,然后建议将镜头作为替代解决方案。
一个易于修复的编译错误
首先,您的数据定义会产生错误,因为 的类型Visible
不以Property
. 你想要这个:
data Property a where
Position :: Property PositionP
Left :: Property (Integer -> StyleUnit)
Visible :: Property Bool
一个问题Left
现在您可以编写以下内容:
setProperty :: Property a -> a -> IO ()
setProperty = undefined
但是 的类型存在问题setProperty Left
,因为您可以签入ghci
(您可能希望使其import Prelude hiding (Left)
正常工作)。
:t setProperty Left
setProperty Left :: (Integer -> StyleUnit) -> IO ()
我不认为那是你想要的类型。你可能想要Integer -> StyleUnit -> IO ()
。
进入IO ()
数据类型
实现这一目标的最简单方法是将 移动IO ()
到Property
数据类型中:
data Property a where
Position :: Property (PositionP -> IO ())
Left :: Property (Integer -> StyleUnit -> IO ())
Visible :: Property (Bool -> IO ())
setProperty :: Property a -> a
setProperty = undefined
这可能适用于setProperty
,但不清楚如何编写getProperty
,我猜你也想拥有。
使用对
也许最好只使用一对值和单位:
data Property a where
Position :: Property PositionP
Left :: Property (Integer, StyleUnit)
Visible :: Property Bool
setProperty :: Property a -> a -> IO ()
setProperty = undefined
这给了你:
:t setProperty Left
setProperty Left :: (Integer, StyleUnit) -> IO ()
您应该能够实施。
这真的是要走的路吗?
在不知道你问题的背景的情况下,我不能说这是否真的是要走的路。对于一个简单的目标来说,这似乎是相当复杂的技术。setPosition
和setLeft
有什么问题setVisible
?如果您只想将 setter 和 getter 组合成一个抽象,您可能需要研究镜头。