Haskell 哈斯克尔:最小位置

Haskell 哈斯克尔:最小位置,haskell,Haskell,我是哈斯克尔术语的初学者。我必须做一个显示所有最小位置的练习。 例如:[1,2,3,1,1]=>0,3,4这些是最小位置。 我试着用两种方法来做这件事,但都不管用。 有人能帮我做一个递归版本吗 第一: findPos :: [Int]->Int->[Int] findPos list minimum (list) = [index | (index, e) <- zip [0..] list, e == minimum (list)] findPos::[Int]->Int-

我是哈斯克尔术语的初学者。我必须做一个显示所有最小位置的练习。 例如:[1,2,3,1,1]=>0,3,4这些是最小位置。 我试着用两种方法来做这件事,但都不管用。 有人能帮我做一个递归版本吗

第一:

findPos :: [Int]->Int->[Int]
findPos list minimum (list) = [index | (index, e) <- zip [0..] list, e == minimum (list)]
findPos::[Int]->Int->[Int]
findPos列表最小值(list)=[index |(index,e)Int->[Int]
findPos列表(最小el)=[index |(index,e)Int
最小x=如果(尾部(x)=[]),则头部(x)
其他
其中n=最小值(尾部(x))
n=如果n
您的代码有问题 这完全是错误的。您稍后会找到最小值(使用
最小值列表
);不需要传递它:

findPos :: [Int] -> [Int]
findPos list = ...
我的解决方案 不是递归的,但我个人会这么做

我非常喜欢拉链解决方案,我不知道你为什么选择理解

  • 找到最小的元素
  • 使用
    [0..]
    压缩数据
  • 根据
    snd
    等于最小元素筛选出数据
  • 取出结果元组的
    fst

  • 剧透
    代码的严重问题是函数定义的左边有一些奇怪的东西

    在第一种情况下,您有:

    findPos :: [Int] -> Int-> [Int]
    findPos list minimum (list) = …
    
    这意味着什么?根据您给
    findPos
    的签名判断,它包含一个列表和我们正在寻找的元素。因此定义必须是:

    findPos list m = [index | (index, e) <- zip [0..] list, e == m]
    
    您可以将定义更改为:

    findPos :: [Int] -> [Int]
    findPos list = [index | (index, e) <- zip [0..] list, e == minim list]
    

    <> P> >您的<代码> MIIM几乎是正确的,除了定义了<代码> N< /代码>两次。

    < P>作为早期答案的一个变体,让我们考虑一个解决方案,在这里我们准确地访问输入列表的每一个元素。就像前面的答案,这不是一个明确的递归解决方案,而是使用递归函数<代码>foldr

    -- | Accumulate function
    --
    acc :: Ord a => (t, a) -> ([t], a) -> ([t], a)
    acc (i, x) z@(is, y) = case compare x y of
      LT -> ([i], x)   -- a new minimum! reinit the list of mins
      EQ -> (i:is, y)  -- equal minimum; add to the list of mins
      _  -> z          -- larger than min; accumulator unchanged
    
    findPos = (Bounded a, Ord a) => [a] -> [Int]
    findPos = fst . foldr acc ([], maxBound) . zip [(0 :: Int)..]
    
    因此,我们用数字列表
    zip
    标记(从零开始计数),将累加器初始化为
    ([],maxBound)
    (初始最小值是可能的最大值),然后提取输入中最小值的索引列表

    为了消除
    Bounded
    类型类约束(因此
    findPos
    可以与
    Integer
    或其他无界有序类型一起工作),可以应用
    Maybe
    类型构造函数,我将其留作练习


    跟踪“看到的最小值”以及看到该值的索引,可以构建一个流处理机器,您可以随时询问“到目前为止(可能无限)输入流中最小值的索引是什么。”

    只有一个小细节:在OP中,索引从
    0开始,因此无限索引列表必须是
    [0..]
    findPos list m = [index | (index, e) <- zip [0..] list, e == m]
    
    findPos' :: [Int] -> [Int]
    findPos' list = findPos list (minim list)
    
    findPos :: [Int] -> [Int]
    findPos list = [index | (index, e) <- zip [0..] list, e == minim list]
    
    minim :: [Int] -> Int
    minim (x : []) = x
    minim (x : xs) = if x < m then x else m
      where
        m = minim xs
    
    -- | Accumulate function
    --
    acc :: Ord a => (t, a) -> ([t], a) -> ([t], a)
    acc (i, x) z@(is, y) = case compare x y of
      LT -> ([i], x)   -- a new minimum! reinit the list of mins
      EQ -> (i:is, y)  -- equal minimum; add to the list of mins
      _  -> z          -- larger than min; accumulator unchanged
    
    findPos = (Bounded a, Ord a) => [a] -> [Int]
    findPos = fst . foldr acc ([], maxBound) . zip [(0 :: Int)..]