-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathexample.idr
More file actions
101 lines (78 loc) · 2.8 KB
/
example.idr
File metadata and controls
101 lines (78 loc) · 2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
module Main
import Python
import Python.Prim
import Python.Exceptions
-- These modules contain signatures for Python libraries.
import Python.Lib.Os
import Python.Lib.Requests
import Python.Lib.BeautifulSoup
import Python.Lib.Queue
import Python.Lib.Threading
%default total
-- Even though field names are strings,
-- everything is typechecked according to the signatures imported above.
partial
main : PIO ()
main = do
reqs <- Requests.import_
-- (/) extracts the named attribute
-- ($) calls a function
-- (/.) and ($.) work with pure LHS
-- (/:) and ($:) work with monadic LHS (useful for chaining)
--
-- equivalent to: session = reqs.Session()
session <- reqs /. "Session" $. []
-- equivalent to: html = session.get("http://idris-lang.org").text
-- Notice that chaining is not a problem.
html <- session /. "get" $. ["http://idris-lang.org"] /: "text"
-- import Beautiful Soup
bs4 <- BeautifulSoup.import_
-- construct soup from HTML
soup <- bs4 /. "BeautifulSoup" $. [html, Parsers.HTML]
-- get the iterator over <li> elements, given by CSS selector
features <- soup /. "select" $. ["div.entry-content li"]
-- print all <li> elements as features
putStrLn' $ "Idris has got the following exciting features:"
count <- iterate features 0 $ \i : Int, li : Obj Element => do
-- collect : Iterator a -> PIO (List a)
line <- concat <$> collect (li /. "strings")
putStrLn' $ show (i+1) ++ ". " ++ line
pure $ i + 1
putStrLn' $ "Total number of features: " ++ show count
putStrLn' ""
-- ### Concurrency ###
let thread : (String -> PIO Nat) = \name => do
putStrLn' $ "thread " ++ name ++ " starting"
html <- session /. "get" $. ["http://idris-lang.org"] /: "text"
putStrLn' $ "thread " ++ name ++ " done"
pure $ length html
thrA <- forkPIO $ thread "A"
thrB <- forkPIO $ thread "B"
resA <- wait thrA
resB <- wait thrB
putStrLn' $ "thread A says " ++ show resA
putStrLn' $ "thread B says " ++ show resB
putStrLn' ""
-- ### Exceptions ###
os <- Os.import_
putStrLn' "And now, let's fail!"
-- the standard try-catch variant
try (do
os /. "mkdir" $. ["/root/hello"]
putStrLn' $ "Something's wrong, your root's homedir is writable!"
) `catch` (\etype, e => case etype of
OSError => putStrLn' $ " -> (1) everything's fine: " ++ showException e
_ => raise e
)
-- Idris sugar, originally used in Effects
OK ret <- try $ os /. "mkdir" $. ["/root/hello"]
| Except OSError e => putStrLn' (" -> (2) everything's fine: " ++ showException e)
| Except _ e => raise e
putStrLn' $ "Your root could probably use some security lessons!"
exports : FFI_Export FFI_Py "example.py" []
exports =
Fun greet "greet" $
End
where
greet : String -> PIO ()
greet name = putStrLn' $ "Hello " ++ name ++ "!"