Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 避免GHCI中出现不适当的非详尽模式匹配警告 在您将其视为重复之前_Haskell_Pattern Matching_Warnings_Suppress Warnings_Non Exhaustive Patterns - Fatal编程技术网

Haskell 避免GHCI中出现不适当的非详尽模式匹配警告 在您将其视为重复之前

Haskell 避免GHCI中出现不适当的非详尽模式匹配警告 在您将其视为重复之前,haskell,pattern-matching,warnings,suppress-warnings,non-exhaustive-patterns,Haskell,Pattern Matching,Warnings,Suppress Warnings,Non Exhaustive Patterns,我至少在2018年9月看到了这一点(尽管你可以在一个完整的文件中看到) 但也许有其他方式让GHCI知道每个案件事实上都在处理中 问题 我有时使用一个习语来写一个函数,其中第一个定义(S)对一些谓词和返回词进行测试,而其他的定义则考虑在运算实际意义上的参数。每当我这样做时,我会得到一个“模式匹配(es)是非穷举的”错误,但我确实在检查每一个条件 例子 (有关激发此玩具示例的真实代码,请参见例如pExprToHExpr的定义) 此代码: {-# LANGUAGE ViewPatterns #-}

我至少在2018年9月看到了这一点(尽管你可以在一个完整的文件中看到)

但也许有其他方式让GHCI知道每个案件事实上都在处理中

问题 我有时使用一个习语来写一个函数,其中第一个定义(S)对一些谓词和返回词进行测试,而其他的定义则考虑在运算实际意义上的参数。每当我这样做时,我会得到一个“模式匹配(es)是非穷举的”错误,但我确实在检查每一个条件

例子 (有关激发此玩具示例的真实代码,请参见例如
pExprToHExpr
的定义)

此代码:

{-# LANGUAGE ViewPatterns #-}

data Cowbell = Cowbell
  deriving Show
data Instrument = Rattle
                | Drums (Maybe Cowbell)
                | Violin
                | Oboe
  deriving Show

pitched :: Instrument -> Bool
pitched Rattle                 = False
pitched (Drums Nothing)        = False
pitched (Drums (Just Cowbell)) = True
pitched Violin                 = True
pitched Oboe                   = True

highestPitch :: Instrument -> Either String Float
highestPitch i@(pitched -> False) =
  Left $ "Instrument " ++ show i ++ " has no pitch."
highestPitch (Drums (Just Cowbell)) = Right 800
highestPitch Violin                 = Right 5000
highestPitch Oboe                   = Right 2000
生成此错误:

example.hs:19:1: warning: [-Wincomplete-patterns]
    Pattern match(es) are non-exhaustive
    In an equation for ‘highestPitch’:
        Patterns not matched:
            Rattle
            (Drums Nothing)
在其他条件下,我只需细分
仪器
类型:

data Percussive = Rattle | Drums
data Pitched    = Violin | Oboe
data Instrument = Percussive Percussive
                | Pitched Pitched

但是(在这个假想的物理中)一套
可能有最高的音高,如果它包括一个
Cowbell
,那么它既不适合
打击式
也不适合
音调
类型。

考虑到
音调
的定义,GHC不会检查穷尽性。因此,检查器基本上忽略了第一个等式,导致发出警告

事实上,从计算科学的角度来看,GHC不能在一般情况下决定这一点,因为存在视图模式时的穷尽性是不可判定的。充其量,GHC可能会使用一些复杂的静态分析,但它只是选择完全忽略
pitched

要使警告静音,我可以看到两个主要选项。第一个是在末尾添加一个catch all case

highestPitch :: Instrument -> Either String Float
highestPitch i@(pitched -> False) =
  Left $ "Instrument " ++ show i ++ " has no pitch."
highestPitch (Drums (Just Cowbell)) = Right 800
highestPitch Violin                 = Right 5000
highestPitch Oboe                   = Right 2000
highestPitch i                      =
  Left $ "Instrument " ++ show i ++ " has no pitch."
  -- we could even use "error", in certain cases
如果我们遵循这条路线,在这个特定的例子中,我们可以去掉第一个等式

highestPitch :: Instrument -> Either String Float
highestPitch (Drums (Just Cowbell)) = Right 800
highestPitch Violin                 = Right 5000
highestPitch Oboe                   = Right 2000
highestPitch i                      =
  Left $ "Instrument " ++ show i ++ " has no pitch."
或者,我们可以将最后一个案例
双簧管
打造成一个包罗万象的案例:

highestPitch :: Instrument -> Either String Float
highestPitch i@(pitched -> False) =
  Left $ "Instrument " ++ show i ++ " has no pitch."
highestPitch (Drums (Just Cowbell)) = Right 800
highestPitch Violin                 = Right 5000
highestPitch _oboe                  = Right 2000   -- must be an Oboe
不过,我不是这种方法的超级粉丝,因为如果
pitched
包含bug,这将悄悄地产生本来不存在的音调


事实上,正如上面在评论中指出的,还有第三种方法:使用
模式同义词和
COMPLETE
pragma说服GHC消除警告。然而,这是更先进的。虽然它在设计库时确实有它的用途,但对于这种特殊情况,它可能有点过头了。

我想颠倒哪个函数是“确定的”。即使乐器已调好音高,您仍然需要指定一些最高音高,而
highestPitch
提供了您需要知道乐器是否已调好音高的所有信息。因此

-- An instrument with a highest pitch is pitched; the others aren't.
pitched :: Instrument -> Bool
pitched = either (const False) (const True) . highestPitch


highestPitch :: Instrument -> Either String Float
highestPitch (Drums (Just Cowbell)) = Right 800
highestPitch Violin                 = Right 5000
highestPitch Oboe                   = Right 2000
highestPitch Rattle = Left "Instrument Rattle has no pitch"
highestPitch (Drums Nothing) = Left "Instrument Drums Nothing has no pitch"

这听起来像是你在要求ghc解决停顿问题。模式同义词和
COMPLETE
pragma?这似乎有点倒退;首先明确定义
highestPitch
,然后定义
pitched=False或True。最高音高
@chepner,
接受两个函数,而不是两个常数。最好做
pitched=isRight。最高音调
@pat是的,我犯了个愚蠢的错误。(我看到@chi为我修正了答案。)不过,在这种情况下,我喜欢建议
或者
,因为它不需要导入
数据。或者
isRight
一样。