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