ElemIndices in Haskell

I wrote some code to get the index of an element

elemIndex :: [String] -> [String] -> [Int]
elemIndex [] [] = []
elemIndex x y = elemIndex True [(elem a y) | a <- x ]

      

is there an alternative way / simulator for doing the above logic?

and also i saw some use

index [] _ = []

      

to return null lists

Could you please explain the use of underscores?

// change 1 it should return the index of the values ​​in the list.

for example: elemIndex ["asde", "zxc", "qwe"] ["qwe", "zxc"]

returns [1,2] as response

thanks

0


a source to share


3 answers


elemIndex

takes two arguments (two lists). Right now, you are recursively calling this an extra argument of type bool (namely True

). It won't work. What you probably want to do is create a helper function, as I showed you an hour ago.

_

, used as a formal argument, matches any input. It has no name and therefore you cannot use what matches.

Also, you probably don't want to use booleans, but integers (to keep track of the counter). The function elem

only indicates whether a value is part of the list, not where it is. Thus, it is of little use to you. Since this appears to be homework, I won't offer a solution to your problem, but perhaps you should split the code in two:

indices :: (Eq t) => [t] -> [t] -> [Integer]
getIndex :: (Eq t) => [t] -> t -> Integer

      

( getIndex

can use a helper function getIndex' :: (Eq t) => [t] -> t -> Integer -> Integer

.)




Edit . One possible solution (which uses a hack, it is better to use a monad Maybe

):

indices :: (Eq t) => [t] -> [t] -> [Integer]
indices xs ys = filter (>= 0) $ map (getIndex xs) ys

getIndex :: (Eq t) => [t] -> t -> Integer
getIndex xs y = getIndex' xs y 0
  where
    getIndex' :: (Eq t) => [t] -> t -> Integer -> Integer
    getIndex' [] _ _                 = -1
    getIndex' (x:xs) y i | x == y    = i
                         | otherwise = getIndex' xs y (i + 1)

      

Monad version Maybe

:

import Data.Maybe

indices :: (Eq t) => [t] -> [t] -> [Integer]
indices xs ys = mapMaybe (getIndex xs) ys

getIndex :: (Eq t) => [t] -> t -> Maybe Integer
getIndex xs y = getIndex' xs y 0
  where
    getIndex' :: (Eq t) => [t] -> t -> Integer -> Maybe Integer
    getIndex' [] _ _                 = Nothing
    getIndex' (x:xs) y i | x == y    = Just i
                         | otherwise = getIndex' xs y (i + 1)

      

And a version that leaves all the hard positions in the standard library:

import Data.List
import Data.Maybe

indices :: (Eq t) => [t] -> [t] -> [Int]
indices xs ys = mapMaybe (`elemIndex` xs) ys

      

+3


a source


index [] _ = []

      

coincides with

index [] x = []

      



except that you cannot use _

the equal sign on the right side.

I don't understand what you want elemIndex

.

+2


a source


I would implement your function like this:

elemIndices acc n []  _ = acc
elemIndices acc n  _ [] = acc
elemIndices acc n (x:x') (y:y') = if x == y then 
                                      elemIndices (n:acc) (n+1) x' y'
                                  else
                                      elemIndices acc (n+1) x' (y:y')

elemIndex x y = reverse $ elemIndices [] 1 x y

      

When the elements in your original list are in the same order as the elements you are looking for, this is much more efficient (no use elem

- tail recursion). Example:

elemIndex [3..7] [4, 6] -- Yields [2, 4]

      

0


a source







All Articles