Difference between revisions of "Monomorphism by annotation of type variables"
Jump to navigation
Jump to search
m |
m |
||
(6 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
[[Category:Proposals]] |
[[Category:Proposals]] |
||
− | |||
− | |||
Introduce the reserved word <code>monomo</code> for rendering type variables monomorphic: |
Introduce the reserved word <code>monomo</code> for rendering type variables monomorphic: |
||
<haskell> |
<haskell> |
||
− | newIORef :: monomo a . a -> IO (IORef a) |
+ | primitive newIORef :: monomo a . a -> IO (IORef a) |
</haskell> |
</haskell> |
||
− | + | Its use in the type signatures for such primitives would prevent the definition of polymorphic references in all contexts - the (abbreviated) canonical example of abuse: |
|
<haskell> |
<haskell> |
||
− | let v = |
+ | let v = unsafeLocalState $ newIORef undefined in |
do writeIORef v ("0" :: [Char]) |
do writeIORef v ("0" :: [Char]) |
||
n <- readIORef v |
n <- readIORef v |
||
Line 19: | Line 17: | ||
...would cause a type error - the type of <code>undefined</code> is also made monomorphic by the annotated type of <code>newIORef</code>, resulting in the |
...would cause a type error - the type of <code>undefined</code> is also made monomorphic by the annotated type of <code>newIORef</code>, resulting in the |
||
− | type <code>monomo a . |
+ | type <code>monomo a . IORef a</code> for <code>v</code>, preventing its dual specialisation to <code>IORef [Char]</code> and <code>IORef Int</code>. |
Definitions relying on the old behaviour would be modified to use, or replaced by new primitives. |
Definitions relying on the old behaviour would be modified to use, or replaced by new primitives. |
||
+ | ---- |
||
+ | |||
+ | <i>For the moment, this proposal can be "emulated" using Haskell's type classes:</i> |
||
+ | <tt> |
||
+ | :module Monomo where |
||
+ | :import Prelude(Bool, Char, Double, Either, Float, Int, IO, Integer) |
||
+ | :import Prelude(Maybe, String) |
||
+ | :import Data.IORef(IORef) |
||
+ | :import Data.STRef(STRef) |
||
+ | :import Data.Time(UTCTime, NominalDiffTime, Day, TimeOfDay) |
||
+ | :import Data.Time(LocalTime, TimeZone, ZonedTime) |
||
+ | :import Data.Time(DiffTime) |
||
+ | :import Data.Time(UniversalTime) |
||
+ | :import Control.Monad.ST(ST) |
||
+ | :import System.Directory(XdgDirectory, XdgDirectoryList, Permissions) |
||
+ | :import System.IO(Handle, IOMode, BufferMode, SeekMode, HandlePosn) |
||
+ | :import System.IO(TextEncoding, Newline, NewlineMode) |
||
+ | :import GHC.Base(RealWorld) |
||
+ | |||
+ | :class Monomo a |
||
+ | |||
+ | : -- add suitable new instances as needed... |
||
+ | :instance Monomo Bool |
||
+ | :instance Monomo BufferMode |
||
+ | :instance Monomo Char |
||
+ | :instance Monomo Day |
||
+ | :instance Monomo DiffTime |
||
+ | :instance Monomo Double |
||
+ | :instance (Monomo a, Monomo b) => Monomo (Either a b) |
||
+ | :instance Monomo Float |
||
+ | :instance Monomo Handle |
||
+ | :instance Monomo HandlePosn |
||
+ | :instance Monomo Int |
||
+ | :instance Monomo Integer |
||
+ | :instance Monomo (IO a) |
||
+ | :instance Monomo IOMode |
||
+ | :instance Monomo LocalTime |
||
+ | :instance Monomo a => Monomo (IORef a) |
||
+ | :instance Monomo a => Monomo [a] |
||
+ | :instance Monomo a => Monomo (Maybe a) |
||
+ | :instance Monomo Newline |
||
+ | :instance Monomo NewlineMode |
||
+ | :instance Monomo NominalDiffTime |
||
+ | :instance Monomo Permissions |
||
+ | :instance Monomo RealWorld |
||
+ | :instance Monomo SeekMode |
||
+ | :instance Monomo (ST s a) |
||
+ | :instance Monomo a => Monomo (STRef s a) |
||
+ | :instance Monomo TextEncoding |
||
+ | :instance Monomo TimeOfDay |
||
+ | :instance Monomo TimeZone |
||
+ | :instance (Monomo a, Monomo b, Monomo c, Monomo d, Monomo e, Monomo f) => Monomo (a, b, c, d, e, f) |
||
+ | :instance (Monomo a, Monomo b, Monomo c, Monomo d, Monomo e) => Monomo (a, b, c, d, e) |
||
+ | :instance (Monomo a, Monomo b, Monomo c, Monomo d) => Monomo (a, b, c, d) |
||
+ | :instance (Monomo a, Monomo b, Monomo c) => Monomo (a, b, c) |
||
+ | :instance (Monomo a, Monomo b) => Monomo (a, b) |
||
+ | :instance Monomo () |
||
+ | :instance Monomo UniversalTime |
||
+ | :instance Monomo UTCTime |
||
+ | :instance Monomo XdgDirectory |
||
+ | :instance Monomo XdgDirectoryList |
||
+ | :instance Monomo ZonedTime |
||
+ | </tt> |
||
+ | ---- |
||
+ | See also: |
||
+ | |||
+ | * [https://gitlab.haskell.org/ghc/ghc/-/issues/19800 GHC ticket 19800: Allow monomorphism annotations for type variables] |
||
+ | |||
[[User:Atravers|Atravers]] 00:21, 7 January 2019 (UTC) |
[[User:Atravers|Atravers]] 00:21, 7 January 2019 (UTC) |
Latest revision as of 08:33, 18 August 2021
Introduce the reserved word monomo
for rendering type variables monomorphic:
primitive newIORef :: monomo a . a -> IO (IORef a)
Its use in the type signatures for such primitives would prevent the definition of polymorphic references in all contexts - the (abbreviated) canonical example of abuse:
let v = unsafeLocalState $ newIORef undefined in
do writeIORef v ("0" :: [Char])
n <- readIORef v
return (n + 1 :: Int)
...would cause a type error - the type of undefined
is also made monomorphic by the annotated type of newIORef
, resulting in the
type monomo a . IORef a
for v
, preventing its dual specialisation to IORef [Char]
and IORef Int
.
Definitions relying on the old behaviour would be modified to use, or replaced by new primitives.
For the moment, this proposal can be "emulated" using Haskell's type classes:
- module Monomo where
- import Prelude(Bool, Char, Double, Either, Float, Int, IO, Integer)
- import Prelude(Maybe, String)
- import Data.IORef(IORef)
- import Data.STRef(STRef)
- import Data.Time(UTCTime, NominalDiffTime, Day, TimeOfDay)
- import Data.Time(LocalTime, TimeZone, ZonedTime)
- import Data.Time(DiffTime)
- import Data.Time(UniversalTime)
- import Control.Monad.ST(ST)
- import System.Directory(XdgDirectory, XdgDirectoryList, Permissions)
- import System.IO(Handle, IOMode, BufferMode, SeekMode, HandlePosn)
- import System.IO(TextEncoding, Newline, NewlineMode)
- import GHC.Base(RealWorld)
- class Monomo a
- -- add suitable new instances as needed...
- instance Monomo Bool
- instance Monomo BufferMode
- instance Monomo Char
- instance Monomo Day
- instance Monomo DiffTime
- instance Monomo Double
- instance (Monomo a, Monomo b) => Monomo (Either a b)
- instance Monomo Float
- instance Monomo Handle
- instance Monomo HandlePosn
- instance Monomo Int
- instance Monomo Integer
- instance Monomo (IO a)
- instance Monomo IOMode
- instance Monomo LocalTime
- instance Monomo a => Monomo (IORef a)
- instance Monomo a => Monomo [a]
- instance Monomo a => Monomo (Maybe a)
- instance Monomo Newline
- instance Monomo NewlineMode
- instance Monomo NominalDiffTime
- instance Monomo Permissions
- instance Monomo RealWorld
- instance Monomo SeekMode
- instance Monomo (ST s a)
- instance Monomo a => Monomo (STRef s a)
- instance Monomo TextEncoding
- instance Monomo TimeOfDay
- instance Monomo TimeZone
- instance (Monomo a, Monomo b, Monomo c, Monomo d, Monomo e, Monomo f) => Monomo (a, b, c, d, e, f)
- instance (Monomo a, Monomo b, Monomo c, Monomo d, Monomo e) => Monomo (a, b, c, d, e)
- instance (Monomo a, Monomo b, Monomo c, Monomo d) => Monomo (a, b, c, d)
- instance (Monomo a, Monomo b, Monomo c) => Monomo (a, b, c)
- instance (Monomo a, Monomo b) => Monomo (a, b)
- instance Monomo ()
- instance Monomo UniversalTime
- instance Monomo UTCTime
- instance Monomo XdgDirectory
- instance Monomo XdgDirectoryList
- instance Monomo ZonedTime
See also:
Atravers 00:21, 7 January 2019 (UTC)