Ответы…
В этом методе я получаю ошибку «Exception: undefined: Eq over a signal».
Это потому, что экземпляр Eq
для Signal c a
таков:
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
из _6 _, но вместо этого сопоставление с образцом. И поскольку первый шаблон всегда совпадает, вы всегда возвращаете False
.
…панировочные сухари…
Отказ от ответственности: я никогда не использовал Kansas-Lava, я понятия не имею об аппаратном программировании, и я в значительной степени новичок в Haskell. Теперь, когда я потерял всякое доверие, давайте начнем путешествие, чтобы получить это Bool
!
Чтобы получить что-то от Signal
, нам нужно знать что такое Signal
:
data Signal (c :: *) a = Signal (S.Stream (X a)) (D a)
Отлично, мы действительно можем сопоставить с образцом Signal
:
bitToBool (Signal _ d) = ...
Что мы можем сделать с d
? d
в нашем случае имеет тип D Bool
. Давайте посмотрим на определение low
, high
, а также помощник _ 19_, чтобы вдохновиться:
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
Обратите внимание на Rep
class a>, это станет важным позже. D
- это newtype
оболочка для Driver E
, _25 _ является одним из конструкторов последнего. Таким образом, мы можем фактически сопоставить с образцом вещи вплоть до toRep
и в настоящее время находимся в этой точке:
bitToBool (Signal _ d) = case unD d of
Lit r -> ...
_ -> False
toRep
имеет двойной fromRep
. И pureX
имеет несколько двойственный unX
< / a>, что в данном случае приводит к Just Bool
или Nothing
. Мы можем использовать fromMaybe
из Data.Maybe
, чтобы завершить наше небольшое путешествие по коду Канзасской лавы:
bitToBool (Signal _ d) =
case unD d of
Lit r -> fromMaybe False . unX . fromRep $ r
_ -> False
К сожалению, я не смог установить kansas-lava в своей системе и, следовательно, не смог протестировать это решение, но, если я что-то не пропустил, все должно, по крайней мере, проверить тип.
… И печальная реальность
Теперь, когда мы увидели, что может быть возможным преобразовать Signal i Bool
обратно в Bool
, это неразумно. Это может быть проверка типа, но unsafePerformIO
тоже.
В конце концов, вы удаляете логическое значение из Signal
контекста. Однако, поскольку в конечном итоге это аппаратное обеспечение / VHDL, это не совсем разумно:
Вы не можете каким-либо разумным способом превратить Сигнал в Bool. Сигналы меняются с течением времени, поэтому сравнение их со статическим логическим значением не имеет особого смысла. Вот почему нет функции сравнения битов. Итак, вы здесь ошиблись. - августа
Фактически, экземпляры Eq
и Ord
для Signal
не должны существовать с моей точки зрения. Кроме того, некоторые конструкторы вообще не следует экспортировать, как подсказывает duplode:
В комментариях к вопросу augustuss поднимает важный вопрос: даже если конструкторы экспортируются, предполагается ли, что вы получите доступ к представлению сигнала? –duplode
Однако в конечном итоге это зависит от ваших мотивов, поскольку на оба первоначальных вопроса были даны ответы. К сожалению, я не могу ответить на вновь возникший вопрос «Имеет ли это смысл?», Это зависит от кого-то другого, у кого больше опыта в этой области.
person
Zeta
schedule
05.05.2014
Signal
? - person Lee Duhem   schedule 05.05.2014low
- это просто переменная в Haskell - она такая же, как если бы вы использовалиx
или_
. Может, вы имели в видуLow
иHigh
? - person Chris   schedule 05.05.2014bitToBool
точно такая же, какbitToBool _ = False
(илиbitToBool = const False
, если хотите). Если вы можете включить предупреждения компилятора ghc в Lava, он будет выдавать предупреждения о совпадении совпадений с шаблоном (поскольку вторая строка недоступна) и неиспользуемых определениях. - person Chris   schedule 05.05.2014