我正在尝试学习haskell并在haskell中实现一些基本算法。我收到的这类消息我并不完全理解。 对于下面的代码,该函数接受一个值和一个列表,并返回列表中匹配值的索引:
#!/usr/bin/env runghc
import Data.Maybe (isNothing, fromJust)
binarySearch :: (Ord a) => a -> [a] -> Maybe Int
binarySearch x [] = Nothing
binarySearch x [y]
| x == y = Just 0
| otherwise = Nothing
binarySearch x ys
| x < centerValue = binarySearch x (fst splitted)
| x >= centerValue = let recurse = binarySearch x (snd splitted)
in if (isNothing recurse) then Nothing else (Just (centerValue + (fromJust recurse)))
where split :: (Ord a) => [a] -> ([a], [a])
split [] = ([],[])
split [x] = ([x], [])
split x = ((take halfIndex x), (take rhalfIndex (reverse x)))
where myLength = length x
halfIndex = myLength `div` 2
rhalfIndex = myLength - halfIndex
splitted = split ys
centerValue = head (snd splitted)
main :: IO()
main = print(binarySearch 5 [1,2,3,4,5])
我收到错误消息:
binarySearch.hs:12:77:
Couldn't match expected type ‘Int’ with actual type ‘a’
‘a’ is a rigid type variable bound by
the type signature for
binarySearch :: Ord a => a -> [a] -> Maybe Int
at binarySearch.hs:4:17
Relevant bindings include
centerValue :: a (bound at binarySearch.hs:21:11)
splitted :: ([a], [a]) (bound at binarySearch.hs:20:11)
ys :: [a] (bound at binarySearch.hs:9:16)
x :: a (bound at binarySearch.hs:9:14)
binarySearch :: a -> [a] -> Maybe Int
(bound at binarySearch.hs:5:1)
In the first argument of ‘(+)’, namely ‘centerValue’
In the first argument of ‘Just’, namely
‘(centerValue + (fromJust recurse))’
不确定发生了什么。有谁知道我应该做的更正以及为什么?
编辑,修正后的代码如下:
#!/usr/bin/env runghc
import Data.Maybe (isNothing, fromJust)
split :: (Ord a) => [a] -> ([a], [a])
split [] = ([],[])
split [x] = ([x], [])
split x = ((take halfIndex x), (drop halfIndex x))
where myLength = length x
halfIndex = myLength `div` 2
binarySearch :: (Ord a) => a -> [a] -> Maybe Int
binarySearch x [] = Nothing
binarySearch x [y]
| x == y = Just 1
| otherwise = Nothing
binarySearch x ys
| x < centerValue = binarySearch x (fst splitted)
| x >= centerValue = let recurse = binarySearch x (snd splitted)
in if (isNothing recurse)
then Nothing
else (Just (centerValueIndex + (fromJust recurse)))
where splitted = split ys
centerValue = head (snd splitted)
centerValueIndex = (length ys) `div` 2
main :: IO()
main = print(binarySearch 8 [1,2,3,4,5,8])
答案 0 :(得分:3)
根据我对二进制搜索实现的理解,您希望获得列表中特定元素的索引。因为binarySearch
的类型签名返回Maybe Int
,我假设Int应该是索引。
如果是这种情况,我相信代码行:
in if (isNothing recurse) then Nothing else (Just (centerValue + (fromJust recurse)))
您正在尝试计算正确的索引。但您使用的是centerValue
,内容,类型为a
,而不是索引,其类型应为{{1} }。除了Int
之外,您可能还需要定义centerValueIndex
。这应该可以解决编译错误。
但是,我也注意到你的实现中存在另一个问题,我不想破坏自己找到它的乐趣,但正如一个提示,问题出在centerValue
实现中。
我自己只知道很少Haskell,但希望这可以帮助。