Написание ПОЛНОЙ прагмы для синонима полиморфного паттерна? - PullRequest
6 голосов
/ 30 июня 2019

У меня есть следующий код, и я не знаю, что следует кормить на ??.Или полиморфные шаблоны не могут быть завершены?

{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns    #-}

module Data.Tuple.Single.Class
  ( Single (..)
  , pattern Single
  ) where

class Single t where
  wrap :: a -> t a
  unwrap :: t a -> a

pattern Single :: Single t => a -> t a
pattern Single a <- (unwrap -> a) where
  Single a = wrap a

{-# COMPLETE Single :: ?? #-}

В документе GHC сказано, что, когда все совпадения полиморфны, вы должны набирать conlike.

При создании ?? () сборник выполнен успешно.Но что значит ()?И GHC говорит, что все еще не является исчерпывающим при использовании.

{-# LANGUAGE PatternSynonyms #-}

{-# OPTIONS_GHC -Wno-orphans #-}

module Data.Tuple.Single.Only
  ( Single (..)
  , pattern Single
  ) where

import           Data.Tuple.Only         (Only (Only, fromOnly))
import           Data.Tuple.Single.Class (Single (unwrap, wrap), pattern Single)

instance Single Only where
  wrap = Only
  unwrap = fromOnly
ghci> Single a = wrap 1 :: Only Int

<interactive>:2:1: warning: [-Wincomplete-uni-patterns]
    Pattern match(es) are non-exhaustive
    In a pattern binding: Patterns not matched: _
  • GHC 8.6.5

1 Ответ

4 голосов
/ 01 июля 2019

Я не эксперт по PatternSynonyms, но, судя по всему, в случае полиморфных шаблонов нам нужно указать точные типы, которые делают их завершенными.

В случае Only это будет:

{-# COMPLETE Single :: Only #-}

Для примера давайте добавим еще один экземпляр к Single:


instance Single Identity where
  wrap = Identity
  unwrap (Identity a) = a

pattern Single :: Single t => a -> t a
pattern Single a <- (unwrap -> a) where
  Single a = wrap a

{-# COMPLETE Single :: Only #-}
{-# COMPLETE Single :: Identity #-}

Что заставляет GHC перестать жаловаться:

λ> Single a = wrap 1 :: Identity Int
λ> Single a = wrap 1 :: Only Int
...