0

我必须创建一个函数,该函数将能够获取两种类型的变量作为输入字符串或 [Int]。

这是我的工作。它将列表列表作为参数,并检查所有列表是否具有相同的长度。如果是,则显示 (m,n) 其中 m 是列表具有的列表数,n 是所有列表的长度(相同)。

size :: [[Int]] -> (Int,Int)
size a = size2 a m n
  where
  m = 0
  n = length (head a)

size2 :: [[Int]] -> Int -> Int -> (Int,Int)
size2 [] m n = (m,n)
size2 a m n
    |  n == length (head a) = size2 (tail a) (m+1) n
    |  otherwise = (0,0)

我让它与 [[Int]] 一起工作,它一定不能在 [String] 输入上工作。

4

3 回答 3

3

答案是将类型签名更改为

size :: [[a]] -> (Int,Int)size2 :: [[a]] -> Int -> Int -> (Int,Int)

但也有更好的方法来制作这个函数,而不是自己浏览列表size2,你可以使用Prelude

如何做到这一点的一个很好的例子是:

size :: [[a]] -> (Int, Int)
size [] = (0,0)
size ls@(x:xs) = 
    if all (\s -> length x == length s) xs 
        then (length ls, length x) 
        else (0,0)

也就是说:如果所有列表的大小都与第一个列表相同,则返回tuple,否则返回(0,0)

这可行,但是如何区分空列表和不包含所有列表大小相同的列表?我们用Maybe

size :: [[a]] -> Maybe (Int, Int)
size [] = Just (0,0)
size ls@(x:xs) = 
    if all (\s -> length x == length s) xs 
        then Just (length ls, length x) 
        else Nothing

*Main> size []
Just (0,0)
*Main> size ["gola","asda"]
Just (2,4)
*Main> size ["gola","asda","s"]
Nothing
于 2013-11-14T19:23:29.947 回答
1

的类型签名size应该是size :: [[a]] -> (Int, Int). 这a是类型变量,可以是任何类型。

[[Int]] -> (Int, Int)它是和的概括,[String] -> (Int, Int)String字符列表相同[Char]

当然,您必须size2相应地更改类型。

作为旁注,最好将定义更改为返回Maybe (Int, Int)类型,这样您就可以区分不同的情况,[]例如[[1],[2,3]].

于 2013-11-14T19:09:18.017 回答
0

您如何创建一个自定义数据类型来满足您的需求?

data Either a b = Left a | Right b
type CharsOrInts = Either [Char] [Int]

现在您可以进行模式匹配:

size Left x = foo x
size Right x = bar x

这样 foo :: String -> YourOutputType, bar :: [Int] -> YourOutputType

于 2013-11-14T23:24:59.673 回答