Haskell - where子句中的函数有一个`Integer`推断参数,但总是用`Int`调用

mil*_*ose 1 haskell type-inference

我的赋值问题是找到字符串中子字符串的所有非重叠出现,并返回找到的出现的起始索引列表.

到目前为止我的代码是:

-- return True when `e` (haystack) starts with `s` (needle)
_startsWith :: String -> String -> Bool
-- Anything starts with the empty string
_startsWith _ "" = True
-- An empty string cannot start with a nonempty string 
_startsWith "" (h:t) = False 
_startsWith (eh:et) (sh:st) = (eh==sh) && (_startsWith et st)

-- look for all occurences of `s` (needle) in `e` (haystack), accumulating 
-- start indices of occurences in `is`
_findAll :: [Integer] -> Integer -> String -> String -> [Integer]
_findAll is i e s
    | null e = is -- end of haystack reached, return indices found so far
    | _startsWith e s = i:(rest $ length s) -- needle found, skip its length
    | otherwise = rest (1::Int) -- needle not found, advance by one character
          -- search the rest of the string after advancing by `skip` characters
    where rest skip = _findAll is (i+skip) (drop skip e) s
Run Code Online (Sandbox Code Playgroud)

GHCi和Hugs给了我不同的类型错误.GHC的一个是:

Couldn't match expected type `Int' with actual type `Integer'
In the first argument of `drop', namely `skip'
In the third argument of `_findAll', namely `(drop skip e)'
In the expression: _findAll is (i + skip) (drop skip e) s
Run Code Online (Sandbox Code Playgroud)

拥抱一个是:

Type error in application
*** Expression     : i + skip
*** Term           : i
*** Type           : Integer
*** Does not match : Int
Run Code Online (Sandbox Code Playgroud)

从这里我猜测问题是skip在需要a的上下文和期望的Int上下文中使用的问题Integral,这是无法解决的,因为没有允许这样的类型类.

假设作业限制 - 签名_findAll可能不会改变,最好不要导入除Prelude之外的任何库,绝对不会导入任何基本的apt-get安装Hugs上没有的库 - 我该如何解决这种类型错误?我试着随意地从整数和整个地方洒水到一点点成功,我不熟悉Haskell数字类型的丑陋来解决这个问题.

ham*_*mar 5

一个简单的解决方案是使用通用版本genericDropgenericLength在中找到Data.List.这些适用于任何Integral类型,而不仅仅是Int.