此问题已在此处有答案:
How to reuse a type variable in an inner type declaration(4个答案)
4天前关闭。
我试着写一个 intersperse 函数,它接受一个a
列表的列表,例如。字符串列表,以及一个单个a
,例如char
作为分隔符,并返回a
的列表或String。
例如,如果我打电话
intersperse ',' ["a", "b"]
-- I will get "a,b"
intersperse ',' ["hello"]
-- I will get only "hello"
intersperse ',' ["a", "b", "c"]
-- I will get "a,b,c"
intersperse 1 [[2,3,4], [5,6,7]]
-- I will get [2, 3, 4, 1, 5, 6, 7]
intersperse 1 [[2,3], [4,5], [6,7]]
-- I will get [2, 3, 1, 4, 5, 1, 6, 7]
--
所以我写了如下,它工作正常。
intersperse :: a -> [[a]] -> [a]
intersperse s [] = []
intersperse s (x:[]) = x
intersperse s (x:xs) = loop x xs
where loop a [] = a
loop a (x:xs) = loop (a ++ [s] ++ x) xs
但是如果我在循环函数中添加类型签名,它将无法编译,并且我无法意识到哪里出错了
intersperse :: a -> [[a]] -> [a]
intersperse s [] = []
intersperse s (x:[]) = x
intersperse s (x:xs) = loop x xs
where loop :: [a] -> [[a]] -> [a]
loop a [] = a
loop a (x:xs) = loop (a ++ [s] ++ x) xs
1条答案
按热度按时间9udxz4iz1#
但是如果我在循环函数中添加类型签名,它将无法编译,我无法意识到哪里出错了。
这是因为
where
子句中的a
与顶层的a
不同。您可以启用**ScopedTypeVariables
**扩展[ghc-doc]:然而,
intersperse
函数并不是懒惰地编写的,这意味着对于大型列表,在将结果交给调用者之前将花费大量时间,并且将消耗大量内存,并且对于无限列表,它将进入无限循环,当内存耗尽时将结束。您可以使用以下命令优化函数: