Haskell递归函数和语法 [英] Haskell recursion functions and syntax
问题描述
我对haskell相当陌生,并且负责创建一个接受int和int列表的函数,函数会查找输入的ints位置并返回之前的值,例如[5, 3,4,5,6]会返回4.我有很多问题入门。首先,我不断收到变量不在范围错误中。
fn':: Int-> [Int] - > Int b -1 -1 Int Int Int Int Int Int Int Int Int Int Int Int Int Int Int Int Int Int Int Int Int Int Int Int Int Int Int Int Int Int Int Int Int Int b b b b b b b b
where listail = fn'y(tail)xs
我应该从哪里开始看,还有其他的事情我应该或不应该做的?
亚当斯代码错误
main.hs:3:31:error:
pre>
•与实际类型'[Int]'
无法匹配预期类型'Int'•在表达式中:fn y x2:xs
在'fn'的等式中:
fn y(x1:x2:xs)
| y == x2 = x1
|否则= fn y x2:xs
main.hs:3:36:错误:
•与实际类型为'Int'的
无法匹配预期类型'[Int]'•在'fn'的第二个参数,即'x2'
在'(:)'的第一个参数中,即'fn y x2'
在表达式中:fn y x2:xs
< ;交互式>:3:1:错误:
•变量不在作用域中:main
•也许你的意思是'min'(从Prelude导入)
解决方案您可以使用模式匹配从列表中获取两个值并进行比较。 b
fn :: Int - > [Int] - > Int
fn y(x1:x2:xs)| y == x2 = x1
|否则= fn y(x2:xs)
fn _ _ = -1
注意我的最后一种情况 - 这是失败的情况,当您无法匹配
(x1:x2:xs)
。
或者:
(x1:x2:xs)
也可以拼写为(x1:xs @(x2:_))
。后一种模式比较复杂,但可以让你这样做:
fn :: Int - > [Int] - > Int
fn y(x1:xs @(x2:_))| y == x2 = x1
|否则= fn y xs
fn _ _ = -1
而不是重新加入
$ b!x2
和xs
来进行递归。
$ b
正如gallais在评论中指出的那样:
请注意,更多的多态形式
Eq a => a - > [a] - >一个
。这只是对类型签名的改变
fn :: Eq a => a - > [a] - > a
这可让您与其他人一起使用
fn
有用的类型,即fn'#'我是#1!
给出'1'
此处更好的返回值可能是
Maybe Int
(或者也许a
在多态形式中),因为你将有一些列表不包含搜索词。fn ::公式a => a - > [a] - >也许是
fn y(x1:xs @(x2:_))| y == x2 =只需x1
|否则= fn y xs
fn _ _ = Nothing
I am quite new to haskell and was tasked with creating a function that takes an int and a list of ints, the function would find the inputted ints position and return the value prior to it, ex fn 5 [1,2,3,4,5,6] would return 4. I'm having many problems getting started. First off I keep getting Variable is not in scope errors.
fn' ::Int->[Int]->Int fn' y [] = -1 fn' y (x:xs) |y = (head listail) = x |otherwise = listail where listail = fn' y (tail)xs
Where should I start looking at, and in general are there other things I should or shouldn't do?
Adams code error
main.hs:3:31: error: • Couldn't match expected type ‘Int’ with actual type ‘[Int]’ • In the expression: fn y x2 : xs In an equation for ‘fn’: fn y (x1 : x2 : xs) | y == x2 = x1 | otherwise = fn y x2 : xs main.hs:3:36: error: • Couldn't match expected type ‘[Int]’ with actual type ‘Int’ • In the second argument of ‘fn’, namely ‘x2’ In the first argument of ‘(:)’, namely ‘fn y x2’ In the expression: fn y x2 : xs <interactive>:3:1: error: • Variable not in scope: main • Perhaps you meant ‘min’ (imported from Prelude)
解决方案You can use pattern matching to grab out two values from the list and compare them.
fn :: Int -> [Int] -> Int fn y (x1:x2:xs) | y == x2 = x1 | otherwise = fn y (x2:xs) fn _ _ = -1
Note my last case -- this is the fail case, when you can't match the pattern
(x1:x2:xs)
.Alternatively:
(x1:x2:xs)
could also be spelled(x1:xs@(x2:_))
. The latter pattern is more complicated to read, but lets you do:fn :: Int -> [Int] -> Int fn y (x1:xs@(x2:_)) | y == x2 = x1 | otherwise = fn y xs fn _ _ = -1
rather than re-joining
x2
andxs
to recurse.
As gallais points out in the comments:
Note that this function can take the more polymorphic form
Eq a => a -> [a] -> a
. This is just a change to the type signaturefn :: Eq a => a -> [a] -> a
This lets you use
fn
with other useful types, i.e.fn '#' "I'm #1!"
gives'1'
Also a better return value here might be a
Maybe Int
(or aMaybe a
in the polymorphic form), since you'll have some lists that don't contain the search term.fn :: Eq a => a -> [a] -> Maybe a fn y (x1:xs@(x2:_)) | y == x2 = Just x1 | otherwise = fn y xs fn _ _ = Nothing
这篇关于Haskell递归函数和语法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!