never executed always true always false
1 -- GENERATED by C->Haskell Compiler, version 0.28.8 Switcheroo, 25 November 2017 (Haskell)
2 -- Edit the ORIGNAL .chs file instead!
3
4
5 -- DayCounterConstructor is declared in QuantLib.Internal.CalendarEnum, but its Read instance
6 -- needs `calendar` (QuantLib.Time.Calendar), and CalendarEnum -> Schedule -> CalendarEnum
7 -- would be a cycle if the instance lived there instead -- see deriveReadPlain's comment in
8 -- Internal/Syntax.hs. Deliberate, not a stray orphan.
9 {-# OPTIONS_GHC -Wno-orphans #-}
10 module QuantLib.Time.Schedule
11 (
12 DayCounterConstructor(..)
13 , DayCounter
14 , dayCounter
15 , days
16 , years
17
18 , Schedule
19 , schedule
20 , fromDates
21 , until
22 , dates
23 , DateGenerationRule(..)
24
25 , fromFrequency
26 , toFrequency
27 , parse
28 , add
29 , divide
30 , lessThan
31 , normalize
32 , TimeUnit(..)
33 , Frequency(..)
34 ) where
35 import qualified Foreign.C.String as C2HSImp
36 import qualified Foreign.C.Types as C2HSImp
37 import qualified Foreign.ForeignPtr as C2HSImp
38 import qualified Foreign.Marshal.Utils as C2HSImp
39 import qualified Foreign.Ptr as C2HSImp
40
41
42 import Prelude hiding(until)
43
44 import QuantLib.Time.Date
45 import QuantLib.Internal
46 import QuantLib.Internal.Type
47 import QuantLib.Internal.Common
48 import QuantLib.Internal.CalendarEnum
49 import QuantLib.Time.Calendar (calendar)
50 import System.IO.Unsafe(unsafePerformIO)
51
52
53
54
55
56
57
58 data DateGenerationRule = Backward
59 | Forward
60 | Zero
61 | ThirdWednesday
62 | ThirdWednesdayInclusive
63 | Twentieth
64 | TwentiethIMM
65 | OldCDS
66 | CDS
67 | CDS2015
68 deriving (Enum,Show,Eq,Read)
69
70
71 data Frequency = NoFrequency
72 | Once
73 | Annual
74 | Semiannual
75 | EveryFourthMonth
76 | Quarterly
77 | Bimonthly
78 | Monthly
79 | EveryFourthWeek
80 | Biweekly
81 | Weekly
82 | Daily
83 | OtherFrequency
84 deriving (Show,Eq,Read,Bounded)
85 instance Enum Frequency where
86 succ NoFrequency = Once
87 succ Once = Annual
88 succ Annual = Semiannual
89 succ Semiannual = EveryFourthMonth
90 succ EveryFourthMonth = Quarterly
91 succ Quarterly = Bimonthly
92 succ Bimonthly = Monthly
93 succ Monthly = EveryFourthWeek
94 succ EveryFourthWeek = Biweekly
95 succ Biweekly = Weekly
96 succ Weekly = Daily
97 succ Daily = OtherFrequency
98 succ OtherFrequency = error "Frequency.succ: OtherFrequency has no successor"
99
100 pred Once = NoFrequency
101 pred Annual = Once
102 pred Semiannual = Annual
103 pred EveryFourthMonth = Semiannual
104 pred Quarterly = EveryFourthMonth
105 pred Bimonthly = Quarterly
106 pred Monthly = Bimonthly
107 pred EveryFourthWeek = Monthly
108 pred Biweekly = EveryFourthWeek
109 pred Weekly = Biweekly
110 pred Daily = Weekly
111 pred OtherFrequency = Daily
112 pred NoFrequency = error "Frequency.pred: NoFrequency has no predecessor"
113
114 enumFromTo from to = go from
115 where
116 end = fromEnum to
117 go v = case compare (fromEnum v) end of
118 LT -> v : go (succ v)
119 EQ -> [v]
120 GT -> []
121
122 enumFrom from = enumFromTo from OtherFrequency
123
124 fromEnum NoFrequency = (-1)
125 fromEnum Once = 0
126 fromEnum Annual = 1
127 fromEnum Semiannual = 2
128 fromEnum EveryFourthMonth = 3
129 fromEnum Quarterly = 4
130 fromEnum Bimonthly = 6
131 fromEnum Monthly = 12
132 fromEnum EveryFourthWeek = 13
133 fromEnum Biweekly = 26
134 fromEnum Weekly = 52
135 fromEnum Daily = 365
136 fromEnum OtherFrequency = 999
137
138 toEnum (-1) = NoFrequency
139 toEnum 0 = Once
140 toEnum 1 = Annual
141 toEnum 2 = Semiannual
142 toEnum 3 = EveryFourthMonth
143 toEnum 4 = Quarterly
144 toEnum 6 = Bimonthly
145 toEnum 12 = Monthly
146 toEnum 13 = EveryFourthWeek
147 toEnum 26 = Biweekly
148 toEnum 52 = Weekly
149 toEnum 365 = Daily
150 toEnum 999 = OtherFrequency
151 toEnum unmatched = error ("Frequency.toEnum: Cannot match " ++ show unmatched)
152
153
154
155
156
157
158
159
160
161
162 -- |Constructs a day counter of the given type and (where applicable) convention.
163 qlDayCounter :: (Int) -> (Int) -> IO ((DayCounter))
164 qlDayCounter a1 a2 =
165 let {a1' = fromIntegral a1} in
166 let {a2' = fromIntegral a2} in
167 preErrorCheck $ \a3' ->
168 qlDayCounter'_ a1' a2' a3' >>= \res ->
169 peekDayCounter res >>= \res' ->
170 errorCheck a3'>>
171 return (res')
172
173
174
175 -- |Business/252 day count convention, counting business days per the given calendar.
176 qlDayCounterBusiness252 :: (Calendar) -> IO ((DayCounter))
177 qlDayCounterBusiness252 a1 =
178 withCalendar a1 $ \a1' ->
179 preErrorCheck $ \a2' ->
180 qlDayCounterBusiness252'_ a1' a2' >>= \res ->
181 peekDayCounter res >>= \res' ->
182 errorCheck a2'>>
183 return (res')
184
185
186
187 -- |Actual/Actual (Bond) day counter, using the given schedule's reference periods.
188 actualActualBond' :: (Schedule) -> IO ((DayCounter))
189 actualActualBond' a1 =
190 withSchedule a1 $ \a1' ->
191 preErrorCheck $ \a2' ->
192 actualActualBond''_ a1' a2' >>= \res ->
193 peekDayCounter res >>= \res' ->
194 errorCheck a2'>>
195 return (res')
196
197
198
199 -- |Actual/Actual (ISMA) day counter, using the given schedule's reference periods.
200 actualActualISMA' :: (Schedule) -> IO ((DayCounter))
201 actualActualISMA' a1 =
202 withSchedule a1 $ \a1' ->
203 preErrorCheck $ \a2' ->
204 actualActualISMA''_ a1' a2' >>= \res ->
205 peekDayCounter res >>= \res' ->
206 errorCheck a2'>>
207 return (res')
208
209
210
211 dayCounter :: DayCounterConstructor -> IO DayCounter
212 dayCounter (Business252 x) = qlDayCounterBusiness252 x
213 dayCounter (ActualActualBond' sched) = actualActualBond' sched
214 dayCounter (ActualActualISMA' sched) = actualActualISMA' sched
215 dayCounter x = uncurry qlDayCounter $ mapDayCounter x
216
217 -- |Returns the number of days between two dates.
218 days :: (DayCounter) -> (Day) -> (Day) -> IO ((Int))
219 days a1 a2 a3 =
220 withDayCounter a1 $ \a1' ->
221 withDay a2 $ \a2' ->
222 withDay a3 $ \a3' ->
223 days'_ a1' a2' a3' >>= \res ->
224 let {res' = fromIntegral res} in
225 return (res')
226
227
228
229 -- |Returns the period between two dates as a fraction of year.
230 years :: (DayCounter) -> (Day) -> (Day) -> (Maybe Day) -> (Maybe Day) -> IO ((Double))
231 years a1 a2 a3 a4 a5 =
232 withDayCounter a1 $ \a1' ->
233 withDay a2 $ \a2' ->
234 withDay a3 $ \a3' ->
235 withMaybeDay a4 $ \a4' ->
236 withMaybeDay a5 $ \a5' ->
237 preErrorCheck $ \a6' ->
238 years'_ a1' a2' a3' a4' a5' a6' >>= \res ->
239 let {res' = realToFrac res} in
240 errorCheck a6'>>
241 return (res')
242
243
244
245 -- |Builds a payment schedule by generating dates between effective and termination dates according to the given tenor and rule.
246 schedule :: (Maybe Day) -- ^effectiveDate
247 -> (Day) -- ^terminationDate
248 -> ((Word,TimeUnit)) -- ^tenor
249 -> (Calendar) -- ^calendar
250 -> (BusinessDayConvention) -- ^convention
251 -> (BusinessDayConvention) -- ^terminationDateConvention
252 -> (DateGenerationRule) -- ^rule
253 -> (Bool) -- ^endOfMonth
254 -> (Maybe Day) -- ^firstDate
255 -> (Maybe Day) -- ^nextToLastDate
256 -> IO ((Schedule))
257 schedule a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 =
258 withMaybeDay a1 $ \a1' ->
259 withDay a2 $ \a2' ->
260 let {(a3'1, a3'2) = fromEnumQuantity a3} in
261 withCalendar a4 $ \a4' ->
262 let {a5' = fromEnumC a5} in
263 let {a6' = fromEnumC a6} in
264 let {a7' = (fromIntegral . fromEnum) a7} in
265 let {a8' = C2HSImp.fromBool a8} in
266 withMaybeDay a9 $ \a9' ->
267 withMaybeDay a10 $ \a10' ->
268 preErrorCheck $ \a11' ->
269 schedule'_ a1' a2' a3'1 a3'2 a4' a5' a6' a7' a8' a9' a10' a11' >>= \res ->
270 peekSchedule res >>= \res' ->
271 errorCheck a11'>>
272 return (res')
273
274
275
276 -- |Builds a payment schedule from an explicit list of dates, without checking them for plausibility.
277 fromDates :: ([Day]) -> (Calendar) -- ^calendar
278 -> (BusinessDayConvention) -- ^convention
279 -> (Maybe BusinessDayConvention) -- ^terminationDateConvention
280 -> (Maybe (Word, TimeUnit)) -- ^tenor
281 -> (Maybe DateGenerationRule) -- ^rule
282 -> (Maybe Bool) -- ^endOfMonth
283 -> IO ((Schedule))
284 fromDates a1 a2 a3 a4 a5 a6 a7 =
285 withDayArray a1 $ \(a1'1, a1'2) ->
286 withCalendar a2 $ \a2' ->
287 let {a3' = fromEnumC a3} in
288 let {a4' = fromMaybeEnum a4} in
289 let {(a5'1, a5'2) = fromMaybeEnumQuantity a5} in
290 let {a6' = fromMaybeEnum a6} in
291 let {a7' = fromMaybeBool a7} in
292 preErrorCheck $ \a8' ->
293 fromDates'_ a1'1 a1'2 a2' a3' a4' a5'1 a5'2 a6' a7' a8' >>= \res ->
294 peekSchedule res >>= \res' ->
295 errorCheck a8'>>
296 return (res')
297
298
299
300 -- |truncated schedule
301 -- TODO Introduce another Schedule type with restricted interface?
302 -- moreover, a fixed rate bond can be constructed from a full schedule only!
303 until :: (Schedule) -> (Day) -> IO ((Schedule))
304 until a1 a2 =
305 withSchedule a1 $ \a1' ->
306 withDay a2 $ \a2' ->
307 preErrorCheck $ \a3' ->
308 until'_ a1' a2' a3' >>= \res ->
309 peekSchedule res >>= \res' ->
310 errorCheck a3'>>
311 return (res')
312
313
314
315 -- |returns the dates for the given Schedule object
316 dates :: (Schedule) -> IO (([Day]))
317 dates a1 =
318 withSchedule a1 $ \a1' ->
319 preArray $ \(a2'1, a2'2) ->
320 dates'_ a1' a2'1 a2'2 >>
321 peekDayArray a2'1 a2'2>>= \a2'' ->
322 return (a2'')
323
324
325
326 -- |returns a Period from a given Frequency (e.g. 6M from SemiAnnual)
327 fromFrequency :: (Frequency) -> IO ((Word), (TimeUnit))
328 fromFrequency a1 =
329 let {a1' = (fromIntegral . fromEnum) a1} in
330 preEnum $ \a2' ->
331 preErrorCheck $ \a3' ->
332 fromFrequency'_ a1' a2' a3' >>= \res ->
333 let {res' = fromIntegral res} in
334 peekEnum a2'>>= \a2'' ->
335 errorCheck a3'>>
336 return (res', a2'')
337
338
339
340 -- |returns a Frequency from a given Period (e.g. SemiAnnual from 6M)
341 toFrequency :: (Word,TimeUnit) -> IO ((Frequency))
342 toFrequency a1 =
343 let {(a1'1, a1'2) = fromEnumQuantity a1} in
344 preErrorCheck $ \a2' ->
345 toFrequency'_ a1'1 a1'2 a2' >>= \res ->
346 let {res' = (toEnum . fromIntegral) res} in
347 errorCheck a2'>>
348 return (res')
349
350
351
352 -- |Parses a period from its short-format string representation (e.g. \"6M\").
353 parse :: (String) -> IO ((Int), (TimeUnit))
354 parse a1 =
355 C2HSImp.withCString a1 $ \a1' ->
356 preEnum $ \a2' ->
357 preErrorCheck $ \a3' ->
358 parse'_ a1' a2' a3' >>= \res ->
359 let {res' = fromIntegral res} in
360 peekEnum a2'>>= \a2'' ->
361 errorCheck a3'>>
362 return (res', a2'')
363
364
365
366 addPeriods :: (Int,TimeUnit) -> (Int,TimeUnit) -> IO ((Int), (TimeUnit))
367 addPeriods a1 a2 =
368 let {(a1'1, a1'2) = fromEnumQuantity a1} in
369 let {(a2'1, a2'2) = fromEnumQuantity a2} in
370 preEnum $ \a3' ->
371 preErrorCheck $ \a4' ->
372 addPeriods'_ a1'1 a1'2 a2'1 a2'2 a3' a4' >>= \res ->
373 let {res' = fromIntegral res} in
374 peekEnum a3'>>= \a3'' ->
375 errorCheck a4'>>
376 return (res', a3'')
377
378
379
380 -- |Adds two periods together.
381 add :: (Int, TimeUnit) -> (Int, TimeUnit) -> IO (Int, TimeUnit)
382 add = addPeriods
383
384 -- |Divides a period's length by an integer divisor.
385 divide :: (Int,TimeUnit) -> (Int) -> IO ((Int), (TimeUnit))
386 divide a1 a2 =
387 let {(a1'1, a1'2) = fromEnumQuantity a1} in
388 let {a2' = fromIntegral a2} in
389 preEnum $ \a3' ->
390 preErrorCheck $ \a4' ->
391 divide'_ a1'1 a1'2 a2' a3' a4' >>= \res ->
392 let {res' = fromIntegral res} in
393 peekEnum a3'>>= \a3'' ->
394 errorCheck a4'>>
395 return (res', a3'')
396
397
398
399 -- |Compares two periods, converting to a common time unit as needed.
400 lessThan :: (Int,TimeUnit) -> (Int,TimeUnit) -> IO ((Bool))
401 lessThan a1 a2 =
402 let {(a1'1, a1'2) = fromEnumQuantity a1} in
403 let {(a2'1, a2'2) = fromEnumQuantity a2} in
404 preErrorCheck $ \a3' ->
405 lessThan'_ a1'1 a1'2 a2'1 a2'2 a3' >>= \res ->
406 let {res' = C2HSImp.toBool res} in
407 errorCheck a3'>>
408 return (res')
409
410
411
412 -- |Normalizes a period to the coarsest equivalent time unit (e.g. 12M to 1Y).
413 normalize :: (Int,TimeUnit) -> IO ((Int), (TimeUnit))
414 normalize a1 =
415 let {(a1'1, a1'2) = fromEnumQuantity a1} in
416 preEnum $ \a2' ->
417 preErrorCheck $ \a3' ->
418 normalize'_ a1'1 a1'2 a2' a3' >>= \res ->
419 let {res' = fromIntegral res} in
420 peekEnum a2'>>= \a2'' ->
421 errorCheck a3'>>
422 return (res', a2'')
423
424
425
426 -- Same NOINLINE reasoning as QuantLib.Time.Calendar's own unsafeCalendar (which this can't
427 -- reuse: DayCounterConstructor's Read instance needs its own top-level NOINLINE binding, not
428 -- a shared one, so GHC can't float/duplicate-inline this call site independently of that
429 -- one's).
430 unsafeCalendar :: CalendarConstructor -> Calendar
431 unsafeCalendar = unsafePerformIO . calendar
432 {-# NOINLINE unsafeCalendar #-}
433
434 -- Hand-written, not `deriving`/TH-spliced: DayCounterConstructor's Business252 case carries a
435 -- live Calendar field (see QuantLib.Internal.Syntax.deriveReadPlain's comment for why the
436 -- generated part is spliced back in CalendarEnum.chs instead of here).
437 -- ActualActualBond'/ActualActualISMA' carry a Schedule, which has no small enum-shaped
438 -- readable proxy at all -- they get no alternative here, so parsing their name deliberately
439 -- falls through to the standard Read "no parse" failure.
440 instance Read DayCounterConstructor where
441 readsPrec d r = readDayCounterConstructorPlain d r
442 ++ readParen (d > 10) (\r' ->
443 [ (Business252 c, s1)
444 | ("Business252", s0) <- lex r'
445 , (p, s1) <- readsPrec 11 s0, let c = unsafeCalendar p
446 ]) r
447
448 -- vim: set ff=unix ts=8 sts=2 sw=2 et:
449
450 foreign import ccall safe "QuantLib/Time/Schedule.chs.h qlDayCounter"
451 qlDayCounter'_ :: (C2HSImp.CInt -> (C2HSImp.CInt -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO (C2HSImp.Ptr (CDayCounter))))))
452
453 foreign import ccall safe "QuantLib/Time/Schedule.chs.h qlDayCounterBusiness252"
454 qlDayCounterBusiness252'_ :: ((C2HSImp.Ptr (CCalendar)) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO (C2HSImp.Ptr (CDayCounter)))))
455
456 foreign import ccall safe "QuantLib/Time/Schedule.chs.h qlDayCounterActualActualBond"
457 actualActualBond''_ :: ((C2HSImp.Ptr (CSchedule)) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO (C2HSImp.Ptr (CDayCounter)))))
458
459 foreign import ccall safe "QuantLib/Time/Schedule.chs.h qlDayCounterActualActualISMA"
460 actualActualISMA''_ :: ((C2HSImp.Ptr (CSchedule)) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO (C2HSImp.Ptr (CDayCounter)))))
461
462 foreign import ccall safe "QuantLib/Time/Schedule.chs.h qlDayCounterDayCount"
463 days'_ :: ((C2HSImp.Ptr (CDayCounter)) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO C2HSImp.CInt))))
464
465 foreign import ccall safe "QuantLib/Time/Schedule.chs.h qlDayCounterYearFraction"
466 years'_ :: ((C2HSImp.Ptr (CDayCounter)) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO C2HSImp.CDouble)))))))
467
468 foreign import ccall safe "QuantLib/Time/Schedule.chs.h qlSchedule"
469 schedule'_ :: (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> ((C2HSImp.Ptr (CCalendar)) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO (C2HSImp.Ptr (CSchedule)))))))))))))))
470
471 foreign import ccall safe "QuantLib/Time/Schedule.chs.h qlSchedule1"
472 fromDates'_ :: (C2HSImp.CUInt -> ((C2HSImp.Ptr C2HSImp.CInt) -> ((C2HSImp.Ptr (CCalendar)) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO (C2HSImp.Ptr (CSchedule)))))))))))))
473
474 foreign import ccall safe "QuantLib/Time/Schedule.chs.h qlScheduleUntil"
475 until'_ :: ((C2HSImp.Ptr (CSchedule)) -> (C2HSImp.CInt -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO (C2HSImp.Ptr (CSchedule))))))
476
477 foreign import ccall safe "QuantLib/Time/Schedule.chs.h qlScheduleDates"
478 dates'_ :: ((C2HSImp.Ptr (CSchedule)) -> ((C2HSImp.Ptr C2HSImp.CUInt) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CInt)) -> (IO ()))))
479
480 foreign import ccall safe "QuantLib/Time/Schedule.chs.h qlPeriodFromFrequency1"
481 fromFrequency'_ :: (C2HSImp.CInt -> ((C2HSImp.Ptr C2HSImp.CInt) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO C2HSImp.CInt))))
482
483 foreign import ccall safe "QuantLib/Time/Schedule.chs.h qlPeriodToFrequency1"
484 toFrequency'_ :: (C2HSImp.CInt -> (C2HSImp.CInt -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO C2HSImp.CInt))))
485
486 foreign import ccall safe "QuantLib/Time/Schedule.chs.h qlPeriodParserParse1"
487 parse'_ :: ((C2HSImp.Ptr C2HSImp.CChar) -> ((C2HSImp.Ptr C2HSImp.CInt) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO C2HSImp.CInt))))
488
489 foreign import ccall safe "QuantLib/Time/Schedule.chs.h qlPeriodAdd1"
490 addPeriods'_ :: (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> ((C2HSImp.Ptr C2HSImp.CInt) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO C2HSImp.CInt)))))))
491
492 foreign import ccall safe "QuantLib/Time/Schedule.chs.h qlPeriodDivide1"
493 divide'_ :: (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> ((C2HSImp.Ptr C2HSImp.CInt) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO C2HSImp.CInt))))))
494
495 foreign import ccall safe "QuantLib/Time/Schedule.chs.h qlPeriodsLT1"
496 lessThan'_ :: (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO C2HSImp.CInt))))))
497
498 foreign import ccall safe "QuantLib/Time/Schedule.chs.h qlPeriodNormalize1"
499 normalize'_ :: (C2HSImp.CInt -> (C2HSImp.CInt -> ((C2HSImp.Ptr C2HSImp.CInt) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO C2HSImp.CInt)))))