Question

I'm writing a function which converts a bit to a bool in Kansas Lava. I can do this in two ways but neither of them works.

The function must do the following:

  • Receive a bit (low or high)
  • Convert it to its corresponding boolean => False if it's low and True of it's high

First method:

bitToBool :: Signal i Bool -> Bool
bitToBool x
  | x==low = False
  | otherwise = True

In this method I get the error "Exception: undefined: Eq over a signal"

Second method:

bitToBool :: Signal i Bool -> Bool
bitToBool low = False
bitToBool high = True

This method always returns False even if the input is high. This should work because in an another piece of code I do the reverse of this, which works.

What am I doing wrong here?

Thanks for the help

Daan

Was it helpful?

Solution

Answers…

In this method I get the error "Exception: undefined: Eq over a signal"

That's because the Eq instance for Signal c a is as such:

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"

You can't compare any two signals.

What am I doing wrong here?

That's not low or high from Utils, but instead pattern matching. And since the first pattern always matches, you always return False.

…breadcrumbs…

Disclaimer: I've never used Kansas-Lava, I have no idea about hardware programming, and I'm pretty much a Haskell beginner. Now that I've lost all my credibility, lets start on a journey to get that Bool!

In order to get something out of a Signal, we need to know what a Signal is:

data Signal (c :: *) a = Signal (S.Stream (X a)) (D a)

Great, we can actually pattern match on Signal:

bitToBool (Signal _ d) = ...

Now what can we do with d? d has type D Bool in our case. Lets have a look at the definition of low, high, and also the helper pureS to get some inspiration:

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

Note the Rep class, it gets important later. D is a newtype wrapper for Driver E, Lit is one of the constructors for the latter. So we can actually pattern match for the things up to toRep and are currently at this point:

bitToBool (Signal _ d) = case unD d of
                             Lit r -> ...
                             _     -> False

toRep has a dual fromRep. And pureX has a somewhat dual unX, which in this case leads to Just Bool or Nothing. We can use fromMaybe from Data.Maybe to finish our little journey through the Kansas Lava code:

bitToBool (Signal _ d) = 
    case unD d of
        Lit r -> fromMaybe False . unX . fromRep $ r
        _     -> False

Unfortunately, I couldn't install kansas-lava on my system and therefore couldn't test this solution, but unless I've missed something everything should at least type check.

…and sad reality

Now that we've seen that it might be possible to transform a Signal i Bool back to a Bool, it isn't wise. It might type check, but so does unsafePerformIO.

In the end, you're removing a boolean value from its Signal context. However, since this is hardware/VHDL at the end, that's not really sensible:

You can't turn a Signal into a Bool in any sensible way. Signals vary over "time", so comparing it with a static boolean makes little sense. That's why there's no comparison function for bits. So, you're on the wrong track here. –augustss

In fact, the Eq and Ord instances for Signal shouldn't exist from my point of view. Also, some of the constructors shouldn't be exported at all, as duplode hints:

augustuss raises an important issue in the question comments: even if the constructors are exported, are you supposed to access the representation of a signal? –duplode

However, it ultimately depends on your motives, as both original questions have been answered. Unfortunately, I cannot answer the new risen question "Does that make sense", that's up to someone else who has more expertise in this field.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top