【Haskell】llvm-hs-pureのサンプルコードで出るパターンマッチ排他警告を修正する

github.com

llvm-hs-pureのREADMEに書いてあるこちらのコードですが、GHCのincomplete-uni-patternsオプションを有効にすると警告が出ます。

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecursiveDo #-}

import Data.Text.Lazy.IO as T

import LLVM.Pretty  -- from the llvm-hs-pretty package
import LLVM.AST hiding (function)
import LLVM.AST.Type as AST
import qualified LLVM.AST.Float as F
import qualified LLVM.AST.Constant as C

import LLVM.IRBuilder.Module
import LLVM.IRBuilder.Monad
import LLVM.IRBuilder.Instruction

simple :: IO ()
simple = T.putStrLn $ ppllvm $ buildModule "exampleModule" $ mdo

  function "add" [(i32, "a"), (i32, "b")] i32 $ \[a, b] -> mdo

    entry <- block `named` "entry"; do
      c <- add a b
      ret c
Pattern match(es) are non-exhaustive
In a lambda abstraction:
    Patterns not matched:
        []
        [_]
        (_:_:_:_)

\[a, b] -> mdoから始まるラムダ式がパターンマッチのケースを網羅していないのが原因なので、とにかく警告をなんとかしたい場合は以下のようにすればOKです。

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecursiveDo #-}

import Data.Text.Lazy.IO as T

import LLVM.Pretty  -- from the llvm-hs-pretty package
import LLVM.AST hiding (function)
import LLVM.AST.Type as AST
import qualified LLVM.AST.Float as F
import qualified LLVM.AST.Constant as C

import LLVM.IRBuilder.Module
import LLVM.IRBuilder.Monad
import LLVM.IRBuilder.Instruction

simple :: IO ()
simple = T.putStrLn $ ppllvm $ buildModule "exampleModule" $ mdo

  function "add" [(i32, "a"), (i32, "b")] i32 $ \x -> case x of
    [a, b] -> mdo

      entry <- block `named` "entry"; do
        c <- add a b
        ret c
    -- 一つ目のパターンにマッチしなかった場合のケースを追加
    _ -> error "Error!"

ちなみに、LambdaCaseというGHC拡張を利用すると、ラムダ式をもっと簡潔に書くことができます。

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecursiveDo #-}
-- GHC拡張を追加
{-# LANGUAGE LambdaCase #-}

import Data.Text.Lazy.IO as T

import LLVM.Pretty  -- from the llvm-hs-pretty package
import LLVM.AST hiding (function)
import LLVM.AST.Type as AST
import qualified LLVM.AST.Float as F
import qualified LLVM.AST.Constant as C

import LLVM.IRBuilder.Module
import LLVM.IRBuilder.Monad
import LLVM.IRBuilder.Instruction

simple :: IO ()
simple = T.putStrLn $ ppllvm $ buildModule "exampleModule" $ mdo

  function "add" [(i32, "a"), (i32, "b")] i32 $ \case -- ここの記述がシンプルになる
    [a, b] -> mdo

      entry <- block `named` "entry"; do
        c <- add a b
        ret c
    _ -> error "Error!"