Haskell位到布尔错误
我正在写一个函数,它在堪萨斯州的熔岩中将一点转换成布尔。 我可以用两种方法来做这件事,但它们都不起作用 该功能必须执行以下操作:Haskell位到布尔错误,haskell,lava,Haskell,Lava,我正在写一个函数,它在堪萨斯州的熔岩中将一点转换成布尔。 我可以用两种方法来做这件事,但它们都不起作用 该功能必须执行以下操作: 接收位(低或高) 将其转换为相应的布尔值=>False(如果它是low)和True(如果它是high) 第一种方法: bitToBool :: Signal i Bool -> Bool bitToBool x | x==low = False | otherwise = True 在这种方法中,我得到错误“异常:未定义:信号上的Eq” 第二种方法
- 接收位(低或高)
- 将其转换为相应的布尔值=>False(如果它是low)和True(如果它是high)
bitToBool :: Signal i Bool -> Bool
bitToBool x
| x==low = False
| otherwise = True
在这种方法中,我得到错误“异常:未定义:信号上的Eq”
第二种方法:
bitToBool :: Signal i Bool -> Bool
bitToBool low = False
bitToBool high = True
即使输入很高,此方法也始终返回False。
这应该是可行的,因为在另一段代码中,我做了与此相反的事情,这是可行的
我做错了什么
谢谢你的帮助
达安回答…
在这种方法中,我得到错误“异常:未定义:信号上的Eq”
这是因为信号ca
的Eq
实例如下:
instance (Rep a, Eq a) => Eq (Signal c a) where
-- Silly question; never True; can be False.
(Signal _ _) == (Signal _ _) = error "undefined: Eq over a Signal"
你不能比较任何两个信号
我做错了什么
这不是来自的low
或high
,而是模式匹配。因为第一个模式总是匹配的,所以您总是返回False
…面包屑…
免责声明:我从未使用过堪萨斯熔岩,我对硬件编程一无所知,而且我基本上是一个Haskell初学者。现在,我已经失去了所有的信誉,让我们开始一段旅程,去获得那个Bool
为了从信号中获得一些信息
,我们需要知道:
很好,我们可以在信号上进行模式匹配:
bitToBool (Signal _ d) = ...
现在我们可以用d
做什么<在我们的例子中,code>d
具有类型d Bool
。让我们看一下的定义,以及帮助者,以获得一些灵感:
pureS :: (Rep a) => a -> Signal i a
pureS a = Signal (pure (pureX a)) (D $ Lit $ toRep $ pureX a)
high :: (sig ~ Signal i) => sig Bool
high = pureS True
low :: (sig ~ Signal i) => sig Bool
low = pureS False
请注意,以后它会变得很重要。驱动程序E的包装器是后者的构造函数之一。因此,我们可以实际匹配到toRep
的模式,目前处于:
bitToBool (Signal _ d) = case unD d of
Lit r -> ...
_ -> False
他有双重身份。并且具有某种双重性,在本例中,这会导致仅Bool
或Nothing
。我们可以使用fromMaybe
from数据。也许
可以完成我们穿越堪萨斯熔岩代码的小旅程:
bitToBool (Signal _ d) =
case unD d of
Lit r -> fromMaybe False . unX . fromRep $ r
_ -> False
不幸的是,我无法在我的系统上安装kansas lava,因此无法测试此解决方案,但除非我遗漏了某些内容,否则所有内容至少都应该进行类型检查
…和悲惨的现实
现在我们已经看到,将信号i Bool
转换回Bool
可能是不明智的。它可能会键入check,但unsafePerformIO
也会键入check
最后,您将从其信号
上下文中删除一个布尔值。但是,由于这最终是硬件/VHDL,因此这并不明智:
你不能以任何明智的方式把信号变成废话。信号随时间而变化,因此将其与静态布尔值进行比较毫无意义。这就是为什么位没有比较函数的原因。所以,你走错了方向 事实上,在我看来,
Signal
的Eq
和Ord
实例不应该存在。此外,一些构造函数根本不应该导出,duplode提示:
Augustus在问题注释中提出了一个重要问题:即使构造函数被导出,您是否应该访问信号的表示 然而,这最终取决于你的动机,因为两个最初的问题都得到了回答。不幸的是,我无法回答新出现的问题“这有意义吗”,这取决于在这一领域拥有更多专业知识的其他人。答案… 在这种方法中,我得到错误“异常:未定义:信号上的Eq” 这是因为
信号ca
的Eq
实例如下:
instance (Rep a, Eq a) => Eq (Signal c a) where
-- Silly question; never True; can be False.
(Signal _ _) == (Signal _ _) = error "undefined: Eq over a Signal"
你不能比较任何两个信号
我做错了什么
这不是来自的low
或high
,而是模式匹配。因为第一个模式总是匹配的,所以您总是返回False
…面包屑…
免责声明:我从未使用过堪萨斯熔岩,我对硬件编程一无所知,而且我基本上是一个Haskell初学者。现在,我已经失去了所有的信誉,让我们开始一段旅程,去获得那个Bool
为了从信号中获得一些信息
,我们需要知道:
很好,我们可以在信号上进行模式匹配:
bitToBool (Signal _ d) = ...
现在我们可以用d
做什么<在我们的例子中,code>d
具有类型d Bool
。让我们看一下的定义,以及帮助者,以获得一些灵感:
pureS :: (Rep a) => a -> Signal i a
pureS a = Signal (pure (pureX a)) (D $ Lit $ toRep $ pureX a)
high :: (sig ~ Signal i) => sig Bool
high = pureS True
low :: (sig ~ Signal i) => sig Bool
low = pureS False
请注意,以后它会变得很重要。驱动程序E的包装器是后者的构造函数之一。因此,我们可以实际匹配到toRep
的模式,目前处于:
bitToBool (Signal _ d) = case unD d of
Lit r -> ...
_ -> False
他有双重身份。并且具有某种双重性,在本例中,这会导致仅Bool
或Nothing
。我们可以使用fromMaybe
from数据。也许
可以完成我们穿越堪萨斯熔岩代码的小旅程:
bitToBool (Signal _ d) =
case unD d of
Lit r -> fromMaybe False . unX . fromRep $ r
_ -> False
不幸的是,我无法在我的系统上安装kansas lava,因此无法测试此解决方案,但除非我遗漏了某些内容,否则所有内容至少都应该进行类型检查
…和悲惨的现实
现在我们已经看到,将信号i Bool
转换回Bool
可能是不明智的。它可能会键入check,但unsafePerformIO
也会键入check
最后,您将从其信号
上下文中删除一个布尔值。但是,由于这最终是硬件/VHDL,因此这并不明智:
你不能以任何明智的方式把信号变成废话。信号随时间而变化,因此将其与静态布尔值进行比较毫无意义。这就是为什么位没有比较函数的原因。所以,你走错了方向 事实上,
Eq
和Ord
是符号的实例