Есть два способа выполнить sh то, что вы хотите.
Несколько более старый способ - использовать Proxy # из GH C .Prim, который гарантированно будет стерто во время компиляции.
{-# LANGUAGE GADTs, MagicHash #-}
module Main where
import Data.List
import GHC.Prim
data MyPoly where
MyConstr :: Proxy# a -> a -> (Proxy# a -> a -> Int -> Int) -> MyPoly
listOfPolys :: [MyPoly]
listOfPolys = [MyConstr proxy# 5 (\_ -> (+))
, MyConstr proxy# 10 (\_ -> (+))
, MyConstr proxy# 15 (\_ -> (+))]
Хотя это немного громоздко.
Другой способ заключается в go Proxy
в целом:
{-# LANGUAGE GADTs #-}
module Main where
import Data.List
data MyPoly where
MyConstr :: a -> (a -> Int -> Int) -> MyPoly
listOfPolys :: [MyPoly]
listOfPolys = [ MyConstr 5 (+)
, MyConstr 10 (+)
, MyConstr 15 (+)
]
main = print $ foldl' (\v (MyConstr n a) -> a n v) 0 listOfPolys
В настоящее время у нас есть некоторые инструменты, которые облегчают работу без Proxy
: такие расширения, как, например, AllowAmbiguousTypes
и TypeApplications
, означают, что вы можете применить тип, который вы имеете в виду напрямую. Я не знаю, каков ваш вариант использования, но возьмите этот (надуманный) пример:
import Data.Proxy
asTypeP :: a -> Proxy a -> a
asTypeP x _ = x
readShow :: (Read a, Show a) => Proxy a -> String -> String
readShow p x = show (read x `asTypeP` p)
>>> readShow (Proxy :: Proxy Int) "01"
"1"
Мы хотим прочитать и затем показать значение какого-то типа, поэтому нам нужен способ указать, что фактический тип есть. Вот как бы вы сделали это с расширениями:
{-# LANGUAGE AllowAmbiguousTypes, TypeApplications, ScopedTypeVariables #-}
readShow :: forall a. (Read a, Show a) => String -> String
readShow x = show (read x :: a)
>>> readShow @Int "01"
"1"