继续我在haskell的学习,我需要将几个函数应用于文件。我研究并找到了一些提示,但它不起作用,我遇到了类型系统的问题,可以帮助我吗?我做到了:
import Prelude hiding (Word, lines)
import Data.Char
import System.IO
import Data.List hiding (lines)
type Doc = String
type Line = String
type Word = String
makeIndex :: Doc -> [([Int], Word)]
makeIndex = lines . numLines . allNumWords . sortLs . makelists . almalgamate . shorten
lines :: Doc -> [Line]
lines [] = []
lines texto = takeWhile(/='\n') texto:(lines.dropWhile(=='\n').dropWhile(/='\n')) texto
numLines :: [Line] -> [(Int, Line)]
numLines texto = zip [1.. length texto] texto
numWord :: (Int, Line) -> [(Int, Word)]
numWord (number, line) = [(number, word) | word <- divide line]
divide :: String -> [Word]
divide st = split (dropSpace st)
split :: String -> [Word]
split [] = []
split st = (getWord st) : split (dropSpace (dropWord st))
getWord :: String -> String
getWord [] = []
getWord (x:xs) | elem x whitespace = (x:xs)
| otherwise = dropWord xs
whitespace :: String
whitespace = ['\n', '\t', ' ']
dropSpace :: String -> String
dropSpace [] = []
dropSpace (x:xs) | elem x whitespace = dropSpace xs
| otherwise = (x:xs)
dropWord :: String -> String
dropWord [] = []
dropWord (x:xs) | elem x whitespace = (x:xs)
| otherwise = dropWord xs
allNumWords :: [(Int, Line)] -> [(Int, Word)]
allNumWords = concat.map numPalavra
sortLs :: [(Int, Word)] -> [(Int, Word)]
sortLs [] = []
sortLs (a:x) = sortLs [b | b <- x, compare b a] ++ [a] ++ sortLs [b | b <- x, compare a b]
where compare (n1, w1) (n2, w2) = (w1 < w2) || (w1 == w2 && n1 < n2)
makelist :: [(Int, Word)] -> [([Int], Word)]
makelist = map mklis
where mklis (num, word) = ([num], word)
almalgamate :: [([Int], Word)] -> [([Int], Word)]
almalgamate [] = []
almalgamate [a] = [a]
almalgamate ((n1, w1) : (n2, w2) : rest) | w1 /= w2 = (n1, w1) : almalgamate ((n2, w2) : rest)
| otherwise = almalgamate ((n1++n2, w1) : rest)
shorten :: [([Int], Word)] -> [([Int], Word)]
shorten = filter long
where long (num, palavra) = length palavra > 4
在编译器中,错误是:
in line 18
Coldn't match type `[Char]' -> ([Int], Word)'
Expected type: Doc -> [([Int], Word)]
Actual type: [([Int], Word] -> [Line]
int the expression (repeat all the functions)
in an equation for 'makeIndex' (repeat all the functions)
makeindex中调用的所有函数都显示相同的错误。
GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( C:\Users\xxx\Desktop\makeindex.hs, interpreted )
C:\Users\xxx\Desktop\makeindex.hs:17:6: error:
* Couldn't match type `[Char]' with `([Int], Word)'
Expected type: Doc -> [([Int], Word)]
Actual type: [([Int], Word)] -> [String]
* In the expression:
lines
. numLines
. allNumWords . sortLs . converte . almalgamate . shorten
In an equation for `makeIndex':
makeIndex
= lines
. numLines
. allNumWords . sortLs . makelist . almalgamate . shorten
C:\Users\xxx\Desktop\makeindex.hs:18:6: error:
* Couldn't match type `(Int, Line)' with `Char'
Expected type: [([Int], Word)] -> String
Actual type: [([Int], Word)] -> [(Int, Line)]
* In the second argument of `(.)', namely
`numLines
. allNumWords . sortLs . makelist . almalgamate . shorten'
In the expression:
lines
. numLines
. allNumWords . sortLs . converte . almalgamate . shorten
In an equation for `makeIndex':
makeIndex
= lines
. numLines
. allNumWords . sortLs . makelist . almalgamate . shorten
C:\Users\xxx\Desktop\makeindex.hs:19:6: error:
* Couldn't match type `(Int, Word)' with `[Char]'
Expected type: [([Int], Word)] -> [Line]
Actual type: [([Int], Word)] -> [(Int, Word)]
* In the second argument of `(.)', namely
`allNumWords . sortLs . makelist . almalgamate . shorten'
In the second argument of `(.)', namely
`numLines
. allNumWords . sortLs . makelist . almalgamate . shorten'
In the expression:
lines
. numLines
. allNumWords . sortLs . makelist . almalgamate . shorten
C:\Users\xxx\Desktop\makeindex.hs:21:6: error:
* Couldn't match type `[Int]' with `Int'
Expected type: [([Int], Word)] -> [(Int, Word)]
Actual type: [([Int], Word)] -> [([Int], Word)]
* In the second argument of `(.)', namely
`converte . almalgamate . shorten'
In the second argument of `(.)', namely
`sortLs . converte . almalgamate . shorten'
In the second argument of `(.)', namely
`allNumWords . sortLs . makelist . almalgamate . shorten'
C:\Users\xxx\Desktop\makeindex.hs:22:6: error:
* Couldn't match type `[Int]' with `Int'
Expected type: [([Int], Word)] -> [(Int, Word)]
Actual type: [([Int], Word)] -> [([Int], Word)]
* In the second argument of `(.)', namely `almalgamate . shorten'
In the second argument of `(.)', namely
`converte . almalgamate . shorten'
In the second argument of `(.)', namely
`sortLs . converte . almalgamate . shorten'
Failed, modules loaded: none.
这是问题,匹配类型问题?在第一篇帖子中,我很抱歉对这个问题的描述不好。
答案 0 :(得分:0)
问题似乎是你把参数的顺序混为(.)
。它(基本上)被定义为
(.) :: (b -> c) -> (a -> b) -> a -> c
(f . g) x = f (g x)
首先应用g
,然后将f
应用于结果。
如果你按照相反的顺序排列函数,你的程序将进行类型检查:
makeIndex = shorten . almalgamate . converte . sortLs
. allNumWords . numLines . lines
或者,您可以使用(>>>)
,(.)
的翻转版本:
import Control.Category ((>>>))
makeIndex = lines >>> numLines >>> allNumWords >>> sortLs
>>> converte >>> almalgamate >>> shorten
由于你还没有说出你希望程序做什么,我不能说修改后的版本是否真的正确,但它确实编译