类型如何确定?

时间:2011-04-02 13:03:31

标签: haskell

我写过一些xyz程序,并在屏幕上打印一些东西,非常无关紧要。在这段代码中,我发现如果我删除与我想要打印的内容无关的行,我就会收到错误。

import Data.Array

horizontal inArray limit listLen = [ findProd i j | i<-[1..limit], j<-[1..(limit - listLen)]]
            where 
            findProd a b = product [ inArray!(a,b+k) | k<-[0..(listLen-1)] ]

vertical inArray limit listLen = [ findProd i j | i<-[1..(limit-listLen)], j<-[1..limit]]
            where 
            findProd a b = product [ inArray!(a+k,b) | k<-[0..(listLen-1)] ]

rightDiag inArray limit listLen = [ findProd i j | i<-[1..(limit - listLen)], j<-[1..(limit - listLen)] ]
            where
            findProd a b = product [ inArray!(a+k,b+k) | k<-[0..(listLen-1)] ]

leftDiag inArray limit listLen= [ findProd i j | i <-[1..(limit - listLen)],j<-[listLen..limit] ]
            where
            findProd a b = product [ inArray!(a+k,b-k) | k<-[0..(listLen-1)] ]

solve = do
        x <- readFile "matrix.txt"              
        let limit = 20
        let listLen = 4
        let inArray = listArray ((1,1),(limit,limit)) $ ( map read (words x))
        let maxprod = maximum $ map maximum $ map (\f -> f inArray limit listLen) [horizontal,vertical,rightDiag,leftDiag]
        print inArray

如果我删除了这行

let maxprod = maximum $ map maximum $ map (\f -> f inArray limit listLen) [horizontal,vertical,rightDiag,leftDiag]

我收到了编译错误。怎么样?它甚至与我想要打印的内容无关。

1 个答案:

答案 0 :(得分:5)

您收到的错误消息是:

Ambiguous type variable `a' in the constraints:
  (Read a) arising from a use of `read' at Temp.hs:23:63-66
  (Show a) arising from a use of `print' at Temp.hs:25:9-13
Probable fix: add a type signature that fixes these type variable(s)

因为您已使用print,编译器已决定inarrayShow的实例。删除打印意味着它无法确定。

添加显式类型声明将有助于read的类型为read :: Read a => String -> a(例如,它可以返回任何内容),并且编译器无法现在这是Show的实例。我假设您正在阅读某种数字,因为文件名为matrix.txt?你可以尝试这样的事情。

let readInt = read :: String -> Integer
let inArray = listArray ((1,1),(limit,limit)) $ (map readInt (words x))

现在编译器知道inArray是一个整数数组,因此可以显示。