2014-12-09 87 views
0

我想编写一个函数,接受一个数字i和数字xs和 回报i列表xs位置的列表,计数第一个位置为1。如果i确实 找到元素不会发生xs,然后position返回0Haskell-在列表

到目前为止,我有这样的:

import Data.List 
position :: Int -> [Int] -> Int 
position i xs 
    | i `elem` xs = i `elemIndex` xs 
    | otherwise = 0 

但是当我编译,它提供了以下错误:

Couldn't match expected type ‘Int’ with actual type ‘Maybe Int’

我知道elemIndex返回Maybe Int类型,我定义我的函数返回Int,但我不知道如何去改变它。有任何想法吗?

+0

您可以使用fromJust(在Data.Maybe定义)如果你确信它总是一个Just,就打开它的价值。 – erdeszt 2014-12-09 11:59:29

回答

4

首先,列表索引0…。因此elemIndex将返回Just 0如果i碰巧是您的列表中的第一个元素。

由于elemIndex回报Maybe Int,你可以在它的结果,而不是模式匹配:

import Data.List 

position :: Eq a => a -> [a] -> Int 
position i xs = maybe 0 (+1) $ i `elemIndex` xs 
5

我认为,上述解决方案可以使用maybe功能是一个班轮甚至在haskell的标准前奏中使用zip函数:) 只需用[1 ..]压缩它,然后使用它提供的列表理解。 看看这里的代码:

positions n xs = [y | (y,z) <- zip [1..] xs, z==n]

要查找出现次数的数量,只需使用长度从标准的前奏:

+0

它不需要'import Data.Maybe(也许)'? – 2017-02-17 02:49:27

+0

@StéphaneLaurentno。 '可能'由'Prelude'(重新)导出。 – Zeta 2017-02-17 05:31:51

0

,你可以:

import Data.List (elemIndex) 

position :: Eq a => a -> [a] -> Int 
position i xs = 
    case i `elemIndex` xs of 
     Just n -> n + 1 
     Nothing -> 0