以下两个功能非常相似.它们从[String] n元素中读取[Int]或[Float].如何计算公共代码?我不知道Haskell中支持将类型作为参数传递的任何机制.
readInts n stream = foldl next ([], stream) [1..n]
where
next (lst, x:xs) _ = (lst ++ [v], xs)
where
v = read x :: Int
readFloats n stream = foldl next ([], stream) [1..n]
where
next (lst, x:xs) _ = (lst ++ [v], xs)
where
v = read x :: Float
Run Code Online (Sandbox Code Playgroud)
我是Haskell的初学者级别,因此欢迎对我的代码发表任何评论.
Phi*_* JF 16
Haskell支持高度的多态性.特别是
readAny n stream = foldl next ([], stream) [1..n]
where
next (lst, x:xs) _ = (lst ++ [v], xs)
where
v = read x
Run Code Online (Sandbox Code Playgroud)
有类型
readAny :: (Enum b, Num b, Read a) => b -> [String] -> ([a], [String])
Run Code Online (Sandbox Code Playgroud)
从而
readInts :: (Enum b, Num b) => b -> [String] -> ([Int], [String])
readInts = readAny
readFloats :: (Enum b, Num b) => b -> [String] -> ([Float], [String])
readFloats = readAny
Run Code Online (Sandbox Code Playgroud)
你不需要专门化这种类型.Haskell会自动推断出最常用的类型,readAny这里可以做你想要的.
在Haskell中不能将类型作为参数传递.你很少需要.对于那些必要的情况,您可以通过传递具有所需类型的值来模拟行为.
Haskell有"返回类型多态",所以你真的不应该担心"传递类型" - 很可能函数会在你告诉他们的情况下做你想做的事情.
基本上你想要的是不明确声明类型.相反,推迟声明类型并让推理引擎为您接管.另外,我认为你正在将折叠与地图混为一谈.这就是我接近它的方式.
readList' :: Read a => [String] -> [a]
readList' = map read
ints = readList' ["1", "2"] :: [Int] -- [1, 2]
floats = readList' ["1.0", "2.0"] :: [Float] -- [1.0, 2.0]
Run Code Online (Sandbox Code Playgroud)
要从流中只读取n个内容,请使用 take