Могу ли я получить значения из синонима шаблона? - PullRequest
0 голосов
/ 28 ноября 2018

Предполагая шаблон:

pattern P :: [Int]
pattern P <- a:_

Могу ли я каким-либо образом использовать a в функции f?

f :: [Int] -> Int
f P = a

Приведенный выше код генерируетошибка Not in scope: 'a'.

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Хотите что-то подобное?

{-# LANGUAGE PatternSynonyms, RecordWildCards #-}
module Temp where

pattern Cons :: a -> [a] -> [a]
pattern Cons { car, cdr } <- car:cdr

safeHead :: [a] -> Maybe a
safeHead Cons{..} = Just car
safeHead _ = Nothing

Раньше это вызывало ошибки, но должно работать с последними выпусками GHC .

Имейте в виду, что car и cdr определяются глобально как функции и затемняются локально через RecordWildCards:

ghci> :browse Temp
pattern Cons :: a -> [a] -> [a]
car :: [a] -> a
cdr :: [a] -> [a]
safeHead :: [a] -> Maybe a
0 голосов
/ 28 ноября 2018

Хорошо, это немного смущает, но я обнаружил, что просто делать это работает:

{-# LANGUAGE PatternSynonyms #-}

pattern P :: Int -> [Int]
pattern P a <- a:_

f :: [Int] -> Int
f (P b) = b

main = print $ f [42]

Ключевым моментом здесь является то, что параметр шаблона становится явным, но затем он также передается как bшаблон 1 , который будет соответствовать.Мне не хватало этой части головоломки.

Недостатком является то, что, очевидно, вам необходимо перечислить все части шаблона, который вы хотите использовать.


1 Конечно, это все еще можно назвать a, я просто назвал его по-другому для иллюстрации.

...