<commit_before>module Signal.Stream(Stream, map, fairMerge, merge, mergeMany, fold, filterMap, filter, keepIf, sample, never, timestamp, toSignal, fromSignal) where

{-| Uninitialised signals, that only give updates and don't have the concept of
a current value. Like `Signal.Event.EventStream` (also in this package), only with values. 

Streams of events. Many interactions with the world can be formulated as
a stream of discrete events: mouse clicks, responses from servers, key presses,
etc.
This library provides the basic building blocks for routing these streams of
events to your application logic.

# Mapping
@docs map

# Merging
@docs merge, fairMerge, mergeMany

# Folding
@docs fold

# Filtering
@docs filter, filterMap, keepIf, sample

# Primitive Streams
@docs never, timestamp

# Conversions
@docs toSignal, fromSignal
-}

import Signal exposing ((<~))
import Signal.Extra as SignalE exposing ((~>))
import Signal.Time as SignalT exposing (Time)
import Maybe exposing (Maybe(..))
import Debug

type alias Stream a = Signal (Maybe a)

-- Helper function, unsafe because 
fromJust : Maybe a -> a
fromJust m =
  case m of
    Just a -> a
    Nothing ->
      Debug.crash <| "There was an implementation error somewhere in "
        ++ "Signal.Stream. If you're using the latest version of "
        ++ "Apanatshka/elm-signal-extra, please file an issue (if there isn't "
        ++ "such an issue yet). "

maybeMap2 : (a -> b -> c) -> Maybe a -> Maybe b -> Maybe c
maybeMap2 f l r =
  case (l,r) of
    (Just a, Just b) -> Just (f a b)
    _ -> Nothing

{-| Apply a function to events as they come in. This lets you transform
streams.

    type Action = MouseClick | TimeDelta Float

    actions : Stream Action
    actions =
        map (always MouseClick) Mouse.clicks
-}
map : (a -> b) -> Stream a -> Stream b
map f =
  Signal.map (Maybe.map f)

{-| Apply a function to events as they come in. This lets you transform
streams.

    type Action = MouseClick | TimeDelta Float

    actions : Stream Action
    actions =
        map (always MouseClick) Mouse.clicks
-}
toSignal : a -> Stream a -> Signal a
toSignal a str =
  Signal.merge (Signal.constant <| Just a) str ~> fromJust

{-| Ignore all updates to a signal, so it becomes the constant initial value. 
-}
init : Signal a -> Signal a
init sig = Signal.sampleOn (Signal.constant ()) sig

{-| Get a stream that triggers whenever the signal is *updated*. Note
that an update may result in the same value as before, so the resulting<commit_msg>Fix documentation for Stream.toSignal<commit_after>module Signal.Stream(Stream, map, fairMerge, merge, mergeMany, fold, filterMap, filter, keepIf, sample, never, timestamp, toSignal, fromSignal) where

{-| Uninitialised signals, that only give updates and don't have the concept of
a current value. Like `Signal.Event.EventStream` (also in this package), only with values. 

Streams of events. Many interactions with the world can be formulated as
a stream of discrete events: mouse clicks, responses from servers, key presses,
etc.
This library provides the basic building blocks for routing these streams of
events to your application logic.

# Mapping
@docs map

# Merging
@docs merge, fairMerge, mergeMany

# Folding
@docs fold

# Filtering
@docs filter, filterMap, keepIf, sample

# Primitive Streams
@docs never, timestamp

# Conversions
@docs toSignal, fromSignal
-}

import Signal exposing ((<~))
import Signal.Extra as SignalE exposing ((~>))
import Signal.Time as SignalT exposing (Time)
import Maybe exposing (Maybe(..))
import Debug

type alias Stream a = Signal (Maybe a)

-- Helper function, unsafe because 
fromJust : Maybe a -> a
fromJust m =
  case m of
    Just a -> a
    Nothing ->
      Debug.crash <| "There was an implementation error somewhere in "
        ++ "Signal.Stream. If you're using the latest version of "
        ++ "Apanatshka/elm-signal-extra, please file an issue (if there isn't "
        ++ "such an issue yet). "

maybeMap2 : (a -> b -> c) -> Maybe a -> Maybe b -> Maybe c
maybeMap2 f l r =
  case (l,r) of
    (Just a, Just b) -> Just (f a b)
    _ -> Nothing

{-| Apply a function to events as they come in. This lets you transform
streams.

    type Action = MouseClick | TimeDelta Float

    actions : Stream Action
    actions =
        map (always MouseClick) Mouse.clicks
-}
map : (a -> b) -> Stream a -> Stream b
map f =
  Signal.map (Maybe.map f)

{-| Convert a stream of values into a signal that updates whenever an event
comes in on the stream.

    url : Signal String

    url =
        toSignal "waiting.gif" imageStream

    constant : a -> Signal a

    constant value =
        toSignal value Stream.never
-}
toSignal : a -> Stream a -> Signal a
toSignal a str =
  Signal.merge (Signal.constant <| Just a) str ~> fromJust

{-| Ignore all updates to a signal, so it becomes the constant initial value. 
-}
init : Signal a -> Signal a
init sig = Signal.sampleOn (Signal.constant ()) sig

{-| Get a stream that triggers whenever the signal is *updated*. Note
that an update may result in the same value as before, so the resulting
{'fraction_non_alphanumeric': 0.09121224009415457, 'fraction_numerical': 0.0007846214201647705, 'mean_word_length': 3.321186440677966, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3999277', 'n_tokens_mistral': 1511, 'n_tokens_neox': 1448, 'n_words': 679}