Haskell немного, чтобы bool ошибка
Я пишу функцию, которая немного преобразует в bool в Канзас-Лаве. Я могу сделать это двумя способами, но ни один из них не работает.
Функция должна делать следующее:
- Получите немного (низкий или высокий)
- Преобразуйте его в соответствующий логический => False, если он низкий, и True, если он высокий
Первый метод:
bitToBool :: Signal i Bool -> Bool
bitToBool x
| x==low = False
| otherwise = True
В этом методе я получаю ошибку "Exception: undefined: Eq over a signal"
Второй метод:
bitToBool :: Signal i Bool -> Bool
bitToBool low = False
bitToBool high = True
Этот метод всегда возвращает False, даже если ввод высокий. Это должно работать, потому что в другом фрагменте кода я делаю обратное, что работает.
Что я здесь не так делаю?
Спасибо за помощь
Даан
1 ответ
Ответы...
В этом методе я получаю ошибку "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
от Utils
, но вместо сопоставления с образцом. И поскольку первый шаблон всегда совпадает, вы всегда возвращаете 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
а также помощник pureS
чтобы получить вдохновение:
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
класс, это становится важным позже. D
это newtype
обертка для Driver E
, Lit
является одним из конструкторов для последнего. Таким образом, мы можем на самом деле сопоставить образец для вещей до toRep
и в данный момент на этом этапе:
bitToBool (Signal _ d) = case unD d of
Lit r -> ...
_ -> False
toRep
имеет двойной fromRep
, А также pureX
имеет несколько двойной unX
что в этом случае приводит к 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 каким-либо разумным способом. С течением времени сигналы меняются, поэтому сравнивать их со статическим логическим значением бессмысленно. Вот почему нет функции сравнения для битов. Итак, вы здесь не на том пути. - augustss
На самом деле, Eq
а также Ord
случаи для Signal
не должно существовать с моей точки зрения. Кроме того, некоторые конструкторы не должны быть экспортированы вообще, как подсказки дупло:
augustuss поднимает важную проблему в комментариях к вопросу: даже если конструкторы экспортируются, вы должны получить доступ к представлению сигнала? -duplode
Тем не менее, это в конечном итоге зависит от ваших мотивов, так как оба первоначальных вопроса были даны ответы. К сожалению, я не могу ответить на новый возникший вопрос "Имеет ли это смысл", это зависит от кого-то, кто имеет больше опыта в этой области.