on master help sign in
Make some IO types more specific

Instead of generic FFIs for putStr, print, etc, use IO. While the generic types work fine, they can lead to strange error messages (which is the bigger problem) and make it harder to explain basic IO. The generic versions, which work for all backends that implement read and write primitives, are still available as putStr', print', etc.

commiteb041bc563a1c2fe7c67ac3554789574376389c7 authorEdwin Brady <ecb10@st-andrews.ac.uk> dateMon 2 Nov 2015, 13:30 (11 years ago) parent1a46d58
4 files changed+49−18
CHANGELOG+2 libs/prelude/IO.idr+6−3 libs/prelude/Prelude/Interactive.idr+39−14 src/Idris/Elab/Value.hs+2−1
CHANGELOG+2
@@ -19,6 +19,8 @@ Language updates
1919* Name binding in patterns follows the same rule as name binding for implicits
2020 in types: names which begin with lower case letters, not applied to any
2121 arguments, are treated as bound pattern variables.
22+* Added %deprecate directive, which gives a warning and a message when a
23+ deprecated name is referenced.
2224
2325Library updates
2426---------------
libs/prelude/IO.idr+6−3
@@ -117,11 +117,11 @@ io_return x = MkIO (\w => prim_io_return x)
117117liftPrimIO : (World -> PrimIO a) -> IO' l a
118118liftPrimIO = MkIO
119119
120−call__IO : IO' l a -> PrimIO a
120+call__IO : IO' ffi a -> PrimIO a
121121call__IO (MkIO f) = f (TheWorld prim__TheWorld)
122122
123123-- Concrete type makes it easier to elaborate at top level
124−run__IO : IO' l () -> PrimIO ()
124+run__IO : IO' ffi () -> PrimIO ()
125125run__IO f = call__IO f
126126
127127unsafePerformIO : IO' ffi a -> a
@@ -176,8 +176,11 @@ namespace FFI_C
176176 FFI_C : FFI
177177 FFI_C = MkFFI C_Types String String
178178
179+||| The type of interactive programs, performing some I/O side effects
180+||| and returning a value.
181+||| @res The result type of the program
179182%error_reverse
180−IO : Type -> Type
183+IO : (res : Type) -> Type
181184IO = IO' FFI_C
182185
183186-- Cannot be relaxed as is used by type providers and they expect IO a
libs/prelude/Prelude/Interactive.idr+39−14
@@ -25,33 +25,58 @@ import IO
2525
2626---- some basic io
2727
28+||| Output a string to stdout without a trailing newline, for any FFI
29+||| descriptor
30+putStr' : String -> IO' ffi ()
31+putStr' x = do prim_write x
32+ return ()
33+
2834||| Output a string to stdout without a trailing newline
29−putStr : String -> IO' ffi ()
30−putStr x = do prim_write x
31− return ()
35+putStr : String -> IO ()
36+putStr = putStr'
37+
38+||| Output a string to stdout with a trailing newline, for any FFI
39+||| descriptor
40+putStrLn' : String -> IO' ffi ()
41+putStrLn' x = putStr' (x ++ "\n")
3242
3343||| Output a string to stdout with a trailing newline
34−putStrLn : String -> IO' ffi ()
35−putStrLn x = putStr (x ++ "\n")
44+putStrLn : String -> IO ()
45+putStrLn = putStrLn'
46+
47+||| Output something showable to stdout, without a trailing newline, for any FFI
48+||| descriptor
49+print' : Show a => a -> IO' ffi ()
50+print' x = putStr' (show x)
3651
3752||| Output something showable to stdout, without a trailing newline
38−print : Show a => a -> IO' ffi ()
39−print x = putStr (show x)
53+print : Show a => a -> IO ()
54+print = print'
4055
41−||| Output something showable to stdout, with a trailing newline
42−printLn : Show a => a -> IO' ffi ()
43−printLn x = putStrLn (show x)
56+||| Output something showable to stdout, with a trailing newline, for any FFI
57+||| descriptor
58+printLn' : Show a => a -> IO' ffi ()
59+printLn' x = putStrLn' (show x)
4460
45−||| Read one line of input from stdin, without the trailing newline
46−getLine : IO' ffi String
47−getLine = do x <- prim_read
48− return (reverse (trimNL (reverse x)))
61+||| Output something showable to stdout, with a trailing newline
62+printLn : Show a => a -> IO ()
63+printLn = printLn'
64+
65+||| Read one line of input from stdin, without the trailing newline, for any FFI
66+||| descriptor
67+getLine' : IO' ffi String
68+getLine' = do x <- prim_read
69+ return (reverse (trimNL (reverse x)))
4970 where trimNL : String -> String
5071 trimNL str with (strM str)
5172 trimNL "" | StrNil = ""
5273 trimNL (strCons '\n' xs) | StrCons _ _ = xs
5374 trimNL (strCons x xs) | StrCons _ _ = strCons x xs
5475
76+||| Read one line of input from stdin, without the trailing newline
77+getLine : IO String
78+getLine = getLine'
79+
5580||| Write a single character to stdout
5681putChar : Char -> IO ()
5782putChar c = foreign FFI_C "putchar" (Int -> IO ()) (cast c)
src/Idris/Elab/Value.hs+2−1
@@ -127,7 +127,8 @@ elabExec fc tm = runtm (PAlternative [] FirstSuccess
127127 printtm tm
128128 ])
129129 where
130− runtm t = PApp fc (PRef fc [] (sUN "run__IO")) [pexp t]
130+ runtm t = PApp fc (PRef fc [] (sUN "run__IO"))
131+ [pimp (sUN "ffi") (PRef fc [] (sUN "FFI_C")) False, pexp t]
131132 printtm t = PApp fc (PRef fc [] (sUN "printLn"))
132133 [pimp (sUN "ffi") (PRef fc [] (sUN "FFI_C")) False, pexp t]
133134