    -- Copyright © 2011 National Institute of Aerospace / Galois, Inc.

    {-# LANGUAGE Safe #-}

    -- | Pick values from one of two streams, depending whether a condition is true
    -- or false.
    module Copilot.Language.Operators.Mux
      ( mux
      , ifThenElse
      ) where

    import Copilot.Core (Typed, typeOf)
    import qualified Copilot.Core as Core
    import Copilot.Language.Prelude
    import Copilot.Language.Stream
    import Prelude ()

    -- | Convenient synonym for 'ifThenElse'.
    mux :: Typed a => Stream Bool -> Stream a -> Stream a -> Stream a
    mux :: forall a.
    Typed a =>
    Stream Bool -> Stream a -> Stream a -> Stream a
    mux (Const Bool
    True) Stream a
    t Stream a
    _  = Stream a
    t
    mux (Const Bool
    False) Stream a
    _ Stream a
    f = Stream a
    f
    mux Stream Bool
    b Stream a
    t Stream a
    f             = Op3 Bool a a a -> Stream Bool -> Stream a -> Stream a -> Stream a
    forall a1 b c a.
    (Typed a1, Typed b, Typed c, Typed a) =>
    Op3 a1 b c a -> Stream a1 -> Stream b -> Stream c -> Stream a
    Op3 (Type a -> Op3 Bool a a a
    forall b. Type b -> Op3 Bool b b b
    Core.Mux Type a
    forall a. Typed a => Type a
    typeOf) Stream Bool
    b Stream a
    t Stream a
    f

    -- | If-then-else applied point-wise to three streams (a condition stream, a
    -- then-branch stream, and an else-branch stream).
    --
    -- Produce a stream that, at any point in time, if the value of the first
    -- stream at that point is true, contains the value in the second stream at
    -- that time, otherwise it contains the value in the third stream.
    ifThenElse :: Typed a => Stream Bool -> Stream a -> Stream a -> Stream a
    ifThenElse :: forall a.
    Typed a =>
    Stream Bool -> Stream a -> Stream a -> Stream a
    ifThenElse = Stream Bool -> Stream a -> Stream a -> Stream a
    forall a.
    Typed a =>
    Stream Bool -> Stream a -> Stream a -> Stream a
    mux