0

所以我有这些常量 FilePath 变量(字符串)

s1 , s2 , s3 , s4 ... :: Filepath
s1 = "help.txt"
s2 = "sljdfn"
-- ...

我有一个函数,它采用这些文件路径之一并返回一个 int。

positionInList:: Filepath -> Int
positionInList s1 = 1
positionInList s2 = 2
-- ...

但是,在编译时,我得到了模式匹配冗余警告,并且程序的行为很奇怪,所以我认为这就是问题所在。我将如何解决这个问题?

4

2 回答 2

7

你必须在==这里使用:

positionInList:: Filepath -> Int
positionInList s | s == s1 = 1
                 | s == s2 = 2
.....

否则,作为局部变量positionInList s1 = ...引入,如in ,匹配任何字符串。s1xpositionInList x = ...

或者,使用库函数:

import Data.List

positionInList:: Filepath -> Int
positionInList s = case elemIndex s [s1,s2,s3,....] of
   Just pos -> pos+1
   Nothing  -> error "positionInList: not found!"

positionInList也许 make to return会更好Maybe Int,除非在找不到文件路径时您有一个合理的默认值。

于 2019-08-04T09:31:53.873 回答
3

如果您使用:

positionInList:: Filepath -> Int
positionInList s1 = 1
positionInList s2 = 2

Haskell 将s1s2视为变量(它会影响现有绑定)。这意味着您的函数将始终返回1

然而,Haskell 已经有一个函数来获取列表中的索引elemIndex :: a -> [a] -> Maybe Int,因此你可以定义你positionInList的:

import Data.List(elemIndex)

positionInList :: FilePath -> Maybe Int
positionInList = fmap (1+) . flip elemIndex [s1, s2]

这里fmap (1+)将从零开始的索引映射到从一开始的索引。

返回一个Maybe a我们可以使用的这样Nothing通常比返回一个像-1. fromMaybe :: a -> Maybe a -> a但是,如果您想映射Nothing其他值,我们可以使用,例如:

import Data.List(elemIndex)
import Data.Maybe(fromMaybe)

positionInList :: FilePath -> Int
positionInList = fromMaybe (-1) . fmap (1+) . flip elemIndex [s1, s2]
于 2019-08-04T09:40:41.983 回答