2015-04-22 7 views
6

Ich bin neu auf Ulme und funktionale Programmierung im Allgemeinen. Aber ich benutze Ulme und ich brauche wirklich eine Funktion, die ein Signal (List String) als Eingabe hat und List (Signal String) zurückgibt.Elm-Funktion mit dem Typ: Signal (Liste a) -> Liste (Signal a)

Ich weiß, dass ich wahrscheinlich dieses Problem nicht mit einem besseren architektonischen Entwurf in meinem Programm haben sollte, aber eine Funktion, die dies tun könnte, würde ein großes Problem für mich lösen.

Der Mähdrescher Funktion tut genau das Gegenteil:

combine : List (Signal a) -> Signal (List a) 
combine = List.foldr (map2 (::)) (constant []) 

Ich habe versucht, etwas ähnlich der Funktion zu tun, verbinden aber erfolglos geblieben sind so weit. Irgendwelche Ideen, wie man eine solche Funktion schafft?

Antwort

4

Dies ist nicht möglich, im allgemeinen

Die Inverse combine nicht (allgemein) möglich.
Wenn Sie eine Liste der statischen Größe der Signale haben, dann können Sie combine sie in ein Signal von Listen der statischen Größe. Aber wenn Sie in die andere Richtung gehen, gibt es keine Garantie, dass die Listen im Signal eine statische Größe haben. Daher können Sie nicht "nur" eine Liste daraus erstellen.
(Wenn Sie könnten dann ein normaler Wert vom Typ List eine sich ändernde Größe Signal um den Typ ohne zu zeigen, haben könnte, und Sie würden dynamisch erstellen und Signale in der Liste zu zerstören. Das sind zwei Dinge Elm nicht zulässt.)

Aber mit einigen Einschränkungen ...

Natürlich, wenn Sie wissen, dass die Liste im Signal von einer statischen Größe ist, können Sie eine bestimmte Funktion basierend auf dieser Annahme schreiben; Diese Funktion würde dann zur Laufzeit versagen, wenn der Fall eintritt, dass die Annahme von statischen Größenlisten falsch ist.

unsafe : Maybe a -> a 
unsafeHead m = 
    case m of 
    Just a -> a 
    Nothing -> Debug.crash "unsafe: You're out of luck. The `Maybe` was not a `Just`. " 

uncombine : Int -> Signal (List a) -> List (Signal a) 
uncombine n sig = 
    if n == 0 
    then [] 
    else Signal.map (List.head >> unsafe) sig 
     :: uncombine (n-1) (Signal.map (List.tail >> unsafe) sig) 

(Ich bin mir ziemlich sicher, dass diese Frage auf der elm-discuss Mailingliste einmal diskutiert wurde, aber ich kann es nicht mehr finden)

+0

Danke @Apanatshka für deine Antwort. Ich verstehe, dass die Liste von statischer Größe sein muss, aber weil ich stur bin, wollte ich weiter versuchen und änderte die uncombine Funktion zu diesem: 'uncombine: Signal (Liste a) -> Liste (Signal a) uncombine sig = if (Signal.map istEmpty sig) dann [] else Signal.map (List.head >> unsichere) sig :: uncombine (n-1) (Signal.map (List.tail >> unsichere) sig) '. Aber ich bekomme Typ Mismatch-Fehler, weil die If-Klausel einen Bool-Wert will aber Signal Bool-Wert erhält. Gibt es eine Umgehungsmöglichkeit für dieses Problem? –

+0

Nein, es gibt keine Problemumgehung. Was du versuchst, ist unmöglich. – Apanatshka