Haskell unterstützt einen hohen Grad an Polymorphie. Insbesondere hat
readAny n stream = foldl next ([], stream) [1..n]
where
next (lst, x:xs) _ = (lst ++ [v], xs)
where
v = read x
readAny :: (Enum b, Num b, Read a) => b -> [String] -> ([a], [String])
so
readInts :: (Enum b, Num b, Read a) => [String] -> ([Int], [String])
readInts = readAny
readFloats :: (Enum b, Num b, Read a) => [String] -> ([Float], [String])
readFloats = readAny
Sie brauchen nicht zu spezialisieren, die Art geben. Haskell wird automatisch den allgemeinsten möglichen Typ ableiten, und der readAny
hier wird tun, was Sie wollen.
Es ist nicht möglich, Typen als Argumente in Haskell zu übergeben. Selten würden Sie brauchen. Für die wenigen Fälle, in denen es notwendig ist, können Sie das Verhalten simulieren, indem Sie einen Wert mit dem gewünschten Typ übergeben.
Haskell hat "Rückgabetyp Polymorphismus", also sollten Sie sich wirklich keine Sorgen machen über "den Typ zu übergeben" - Chancen sind, dass Funktionen tun, was Sie wollen, ohne dass Sie es ihnen sagen.
Sie verwenden nicht hier falten müssen, können Sie mit einer einfachen Karte auszukommen. z.B. 'map read stream :: [Int]' Vielleicht sollten Sie auch nachschauen, warum Sie foldr in Haskell statt foull verwenden wollen. –
@EdwardKmett Vielen Dank für Ihren Vorschlag. Was ich wirklich will, ist nur die ersten n Elemente zu lesen und die Liste und den Rest des Streams zurückzugeben. Ich war gestern sehr müde und konnte nicht durchdenken. Ich denke du willst sagen das ich mit foldr den Konstruktor benutzen kann: direkt richtig? Ich schrieb es später als '(Karte gelesen firstn, Ruhe) wo (firstn, Ruhe) = splitAt n stream', ziemlich ähnlich zu dem, was Sie vorgeschlagen. –
Sie müssen nicht 'where' verschachteln; Sie können 'next (lst, x: xs) _ = ...' und 'v = ...' in aufeinander folgende Zeilen setzen. – sdcvvc