Frage

Welche der folgenden sind Sie am ehesten zu schreiben?

r = zip xs $ map sqrt xs

oder

r = [(x, sqrt x) | x <- xs]

Beispielcode im Internet scheint darauf hinzudeuten, dass die ehemalige reichliche und die bevorzugte Art und Weise ist.

War es hilfreich?

Lösung

Ich würde wahrscheinlich schreiben

map (\x -> (x, sqrt x)) xs

Wenn Sie Punkt frei bevorzugen, die oben entspricht (nach Control.Monad und Control.Monad.Instances eingeführt haben)

map (ap (,) sqrt) xs

Eine weitere Alternative, die noch nicht erwähnt ist

zipWith (,) xs (map sqrt xs)

Andere Tipps

Die Menschen, die zu viel Zeit in #haskell verbringen würde wahrscheinlich schreiben, wie

r = map (id &&& sqrt) xs

(&&&) ist ein Spaß combinator in Control.Arrow definiert. Seine eigentliche Art Signatur ist kompliziert, weil es für alle Instanzen von Pfeil verallgemeinert wird. Aber es ist oft mit der (->) Instanz Arrow, die Ergebnisse in dieser Art Signatur verwendet:

(&&&) :: (a -> b) -> (a -> c) -> a -> (b, c)

Obwohl ich neige dazu, sie nicht sehr häufig zu verwenden, in diesem Fall denke ich, dass ich die Liste Verständnis Version bevorzugen würde, da es sauberer ich scheint.

Wenn Sie in Punkt freie Art sind, könnten Sie dieses mögen, auch:

f = zip `ap` map sqrt

ap Leben in Control.Monad und in diesem Fall kann es als S combinator gedacht werden, die Anwendung verallgemeinert in SKI Kalkül :

ap f g x == f x (g x)
ap const const == id

Wie Conal weist darauf hin, das auch von Monade zu Applicative verallgemeinert werden kann thusly (Import Control.Applicative):

f = zip <*> map sqrt

Ich würde wahrscheinlich schreiben map / zip und dann später hatte ich wünsche, das Liste Verständnis geschrieben.

Für bestimmte Arten von Problemen ( Projekt Euler insbesondere ), dieser spezielle Fall kommt so oft, dass ich das schrieb folgende kleinen Helfer:

with :: (a -> b) -> a -> (a,b)
with f a = (a, f a)

Dies ermöglicht Ihr Beispiel geschrieben werden:

r = map (with sqrt) xs

Ich bin eher ein „Old School“ Haskellier, so dass ich zip `ap` map sqrt verwenden würde und es später Refactoring die <*> zu verwenden, anstatt ap.

Applicative ist die neue Monade. (Im Sinne von „was der Cool Haskell Kinder nutzen diese Tage?“)

Ich verwende selten Listenkomprehensionen, aber beide sind Dandy. Verwenden Sie einfach die, die Ihren Code leichter macht zu lesen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top