Написание ПОЛНОЙ прагмы для синонима полиморфного шаблона?

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

{-# 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

person Kazuki Okamoto    schedule 30.06.2019    source источник
comment
В той вики-статье говорится, что вы можете использовать {-# COMPLETE Single :: () #-} — вы пробовали это?   -  person Jon Purdy    schedule 30.06.2019
comment
@JonPurdy Я отразил ваш комментарий.   -  person Kazuki Okamoto    schedule 01.07.2019


Ответы (1)


Я не эксперт по 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
person lehins    schedule 01.07.2019
comment
Дополнение: GHC говорит, что прагмы Orphan COMPLETE не поддерживаются, прагма COMPLETE должна упоминать по крайней мере один конструктор данных или синоним шаблона, определенный в том же модуле. - person Kazuki Okamoto; 02.07.2019