我正在学习函数式编程的入门课程,其中我们使用Haskell。练习的一部分是为输入字符串编写解析器。
然而,我无法解决以下错误,或者得到实际发生的事情。
Parser.hs:29:71:
Couldn't match expected type `String' with actual type `Char'
In the first argument of `readPoint', namely `start'
In the expression: readPoint start
In the expression:
(readLines track, readPoint start, readLine finish)
错误来自这一行:
readTrack str = parseTrack (lines str) where
parseTrack (start : finish : track) = (readLines track, readPoint start, readLine finish)
我期望发生的是,输入字符串被拆分成一个行列表,并传递给parseTrack。然后,parseTrack将使用模式匹配来命名列表中最前面的两个字符串(行)和其他字符串。
然而,我认为正在发生的是finish是列表中的顶部元素,start从该字符串中被分配了顶部字符。
我真的很想知道如何解决这个问题以及实际发生了什么。
谢谢!
解析器。hs
module Parser where
import Types
readFloat :: String -> Float
readFloat str = case reads str of
[] -> error "not a floating point number"
(p,_):_ -> p
readInt :: String -> Int
readInt str = case reads str of
[] -> error "not an integer"
(p,_):_ -> p
readPoint :: String -> Point
readPoint str = parsePoint (words str) where
parsePoint (x : y : _) = (readInt x, readInt y)
readLine :: String -> Line
readLine str = parseLine (words str) where
parseLine (x1 : y1 : x2 : y2 : _) = ((readInt x1, readInt y1), (readInt x2, readInt y2))
readLines :: String -> [Line]
readLines str = parseLines (lines str) where
parseLines (line : rest) = readLine line : parseLines rest
readTrack :: String -> Track
readTrack str = parseTrack (lines str) where
parseTrack (start : finish : track) = (readLines track, readPoint start, readLine finish)
类型。hs
module Types where
type Vector2D = (Int, Int)
type Point = Vector2D
type Line = (Point, Point)
type Velocity = Vector2D
type CarState = (Position, Velocity)
type Position = Vector2D
type Trace = [Position]
type Track = ([Line], Point, Line)
UPD。哦,对不起,我没有理解曲目
意味着多个曲目,必须是[String]
类型。因此,AndrewC的答案更合适
因为在haskell中,模式(x:xs)
意味着如果x
有类型a
,那么xs
必须是类型[a]
你在parseTrack
中的模式意味着类似于(a:a])
的类型
编译器要计算类型a
,首先在右边看到的是读线磁道
。FuncreadLines
具有类型字符串-
parseTrack (start : finish : track : _)
变量track
实际上是一个单行列表,而不是一个包含'\n'
s的字符串。由于您已经将其拆分为行
,因此您可以将readLine映射到它上面,给出:
readTrack str = parseTrack (lines str) where
parseTrack (start:finish:tracks)
= (map readLine tracks, readPoint start, readLine finish)
这里的跟踪:: [String]
,这就是为什么您可以将映射
readLine
放在它们上面-您不需要使用readLines
将其首先拆分为行。(你可以看出这是一个列表,因为它是:
右手边的最后一件事。)
你说
然而,我认为正在发生的是finish是列表中的顶部元素,start从该字符串中被分配了顶部字符。
发生的事情是:因为您要求将readLines跟踪
作为第一个输出,Haskell从那里开始,并且由于您声明
readLines :: String -> [Line]
这意味着track
必须是一个字符串——这是readLines唯一能处理的事情。
首先,您需要记住,:
左侧有一个元素,右侧有一个列表,因此
3:4:stuff
东西
必须是[整数]
,因为它在某些整数元素的右侧。同样,
c:"a string"
表示c必须是字符,因为字符串=[Char]。
在您的代码中,我们已经计算出,track
是一个字符串,这意味着当您编写
(start : finish : track)
start和finish都必须是可以放在字符串前面的元素,因此start和finish都必须是Char。
Haskell然后查看您的代码readPoint start
,但是因为计算出start
具有Char类型,但是
readPoint :: String -> Point
它抱怨Char和String不匹配。
我想你犯了这个错误,因为你忘记了readLines只需要一个字符串,但是它(从名字来看)应该很高兴地需要一个字符串列表。您的parseLines看起来做了类似的事情,但是它需要一个字符串列表,所以可以处理,而readLines需要一个带有换行符的字符串,所以不能处理列表。
假设我想在Haskell中用 错误:
本文向大家介绍正则表达式模式匹配的String方法,包括了正则表达式模式匹配的String方法的使用技巧和注意事项,需要的朋友参考一下 在JavaScript代码中使用正则表达式进行模式匹配经常会用到String对象和RegExp对象的一些方法,例如replace、match、search等方法,以下是对一些方法使用的总结。 String对象中支持正则表达式有4种方法,分别是:search、rep
我必须使函数:: [((String, String), Int)]- 这就是我提出的功能: 输出应该是一个元组列表,其中的字符串与元组x1中的inputWord以及整数x2成对出现 问题是我得到了我认为不应该存在的非详尽模式。 我试图替换与 这使得非穷举模式在列表不为空时消失,但也阻止了函数遍历元组的最后一个元组。
我试图编写函数尾部,它将字符串转换成字符串列表,方式如下: 以下是我的实现: 正如标题所暗示的,这个函数中有一些非详尽的模式。不幸的是,我不明白为什么。 我是哈斯克尔的新手。。。任何帮助都将不胜感激!
问题内容: 我有以下输入, 我想提取所有输入, 除了 包含“ ”的行和包含单个(点)的最后一行。也就是说,我想提取以下内容 我尝试了以下方法 但它不起作用,因为它不会产生任何输出。 问题答案: 实际操作: 别忘了负前瞻,否则您将无法获得任何匹配;-)
我正在编写一个Rust程序来收集每个输入行的第一个字,这有点类似于Unix实用程序。 这让我 我读过《不能作为可变借来》一书,因为它也是作为不可变借来的,但我仍然感到困惑:可变借来发生在第10行,而不可变借来发生在第12行,那么“已经作为不可变借来的变量是作为可变借来的”怎么可能发生呢?至少错误应该是“一个已经作为可变(在第10行)借用的变量被作为不可变(在第12行)借用”。