获取Haskell列表中下一个最小元素的索引

Pho*_*404 6 haskell compiler-errors list

我是Haskell的新手.我对Imperative语言很满意,但没有功能.Haskell是我的第一个函数式语言.

我想弄清楚,如何获取列表中最小元素的索引,其中我定义了最小元素.

让我通过例子来解释.

例如 :

函数签名minList :: x - > [x]

let x = 2
let list = [2,3,5,4,6,5,2,1,7,9,2] 

minList x list --output 1 <- is index
Run Code Online (Sandbox Code Playgroud)

这应该返回1.因为at列表[1]是3.它返回1,因为3是x(= 2)之后的最小元素.

let x = 1
let list = [3,5,4,6,5,2,1,7,9,2] 
minList x list -- output 9 <- is index
Run Code Online (Sandbox Code Playgroud)

它应该返回9,因为列表[9]是2,而2是1. x = 1之后的最小元素,由我定义.

到目前为止我尝试过的.

minListIndex :: (Ord a, Num  a) => a -> [a] -> a
minListIndex x [] = 0
minListIndex x (y:ys) 
            | x > y =  length ys
            | otherwise = m
            where m = minListIndex x ys
Run Code Online (Sandbox Code Playgroud)

当我加载文件时,我收到此错误

• Couldn't match expected type ‘a’ with actual type ‘Int’
      ‘a’ is a rigid type variable bound by
        the type signature for:
          minListIndex :: forall a. (Ord a, Num a) => a -> [a] -> a
        at myFile.hs:36:17
    • In the expression: 1 + length ys
      In an equation for ‘minListIndex’:
          minListIndex x (y : ys)
            | x > y = 1 + length ys
            | otherwise = 1 + m
            where
                m = minListIndex x ys
    • Relevant bindings include
        m :: a (bound at myFile.hs:41:19)
        ys :: [a] (bound at myFile.hs:38:19)
        y :: a (bound at myFile.hs:38:17)
        x :: a (bound at myFile.hs:38:14)
        minListIndex :: a -> [a] -> a (bound at myFile.hs:37:1)
Run Code Online (Sandbox Code Playgroud)

当我修改这样的功能

minListIndex :: (Ord a, Num  a) => a -> [a] -> a
minListIndex x [] = 0
minListIndex x (y:ys) 
            | x > y =  2 -- <- modified...
            | otherwise = 3 -- <- modifiedd
            where m = minListIndex x ys
Run Code Online (Sandbox Code Playgroud)

我再次加载文件然后编译并运行但是不需要输出.

有什么问题

| x > y =  length ys
| otherwise = m
Run Code Online (Sandbox Code Playgroud)

简而言之:基本上,我想找到最小元素的索引,但要高于我在参数/函数签名中定义的x.

我在这里先向您的帮助表示感谢!

max*_*kin 3

minListIndex :: (Ord a, Num  a) => a -> [a] -> a
Run Code Online (Sandbox Code Playgroud)

问题是您试图返回泛型类型的结果a,但它实际上是列表中的索引。

假设您正在尝试评估双精度列表的函数。在这种情况下,编译器应该实例化函数的类型,Double -> [Double] -> Double这是无意义的。

实际上,编译器注意到您正在返回从列表长度派生的内容,并警告您不可能将泛型类型a与具体类型相匹配Int

length ys返回Int,所以你可以尝试这个:

minListIndex :: Ord a => a -> [a] -> Int
Run Code Online (Sandbox Code Playgroud)

关于你原来的问题,似乎你无法用简单的递归来解决它。考虑使用Accumulator定义辅助递归函数。在你的情况下它可以是一对(min_value_so_far, its_index)