Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f481921

Browse files
authoredJul 1, 2023
Fix type inference by exposing classless API (#53)
* Drop unused import * Fix type inference via classless API
1 parent 4ec460a commit f481921

File tree

5 files changed

+281
-51
lines changed

5 files changed

+281
-51
lines changed
 

‎CHANGELOG.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,43 @@ Notable changes to this project are documented in this file. The format is based
55
## [Unreleased]
66

77
Breaking changes:
8+
- Expose Buffer API using typeclass-less API witout removing typeclass API (#53 by @JordanMartinez)
9+
10+
Previously, compiler would fail to infer the type of `Buffer.create 1` as `Effect Buffer`
11+
because the Buffer API was exposed only via the multiparameter typeclass `MonadBuffer`.
12+
Due to the functional dependency between the two parameters, the monadic type cannot be inferred
13+
until the buffer type is known (either `Buffer` or `STBuffer`).:
14+
```purs
15+
import Node.Buffer as Buffer
16+
17+
-- Example 1
18+
main :: Effect Unit
19+
main = do
20+
x <- Buffer.create 1 -- compiler: is this `Int -> Effect Buffer` or `Int -> ST h (STBuffer h)?
21+
pure unit
22+
```
23+
24+
The workaround was to add a type annotation, indicating the `x` is a `Buffer`:
25+
```purs
26+
import Node.Buffer as Buffer
27+
28+
-- Example 2
29+
main :: Effect Unit
30+
main = do
31+
x :: Buffer <- Buffer.create 1 -- compiler: Oh! It's `Int -> Effect Buffer`
32+
pure unit
33+
```
34+
35+
This change does not break anyone's code if one was using a `create` (or another such typeclass member)
36+
to get `Int -> Effect Buffer`. Rather, such users can now drop the `:: Buffer` annotation
37+
(i.e. Example 1 above now compiles).
38+
39+
If one was using `create` to get `forall m buf. MonadBuffer buf m => Int -> m buf`,
40+
then one will need to update their imports:
41+
```diff
42+
-import Node.Buffer (class MonadBuffer)
43+
+import Node.Buffer.Class (class MonadBuffer)
44+
```
845

946
New features:
1047

‎src/Node/Buffer.purs

Lines changed: 122 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,136 @@
22
module Node.Buffer
33
( Buffer
44
, module TypesExports
5-
, module Class
5+
, create
6+
, freeze
7+
, unsafeFreeze
8+
, thaw
9+
, unsafeThaw
10+
, fromArray
11+
, fromString
12+
, fromArrayBuffer
13+
, toArrayBuffer
14+
, read
15+
, readString
16+
, toString
17+
, write
18+
, writeString
19+
, toArray
20+
, getAtOffset
21+
, setAtOffset
22+
, slice
23+
, size
24+
, concat
25+
, concat'
26+
, copy
27+
, fill
628
) where
729

30+
import Prelude
31+
32+
import Data.ArrayBuffer.Types (ArrayBuffer)
33+
import Data.Maybe (Maybe)
834
import Effect (Effect)
935
import Node.Buffer.Class (class MutableBuffer)
10-
import Node.Buffer.Class (class MutableBuffer, concat, concat', copy, create, fill, freeze, fromArray, fromArrayBuffer, fromString, getAtOffset, read, readString, setAtOffset, size, slice, thaw, toArray, toArrayBuffer, toString, unsafeFreeze, unsafeThaw, write, writeString) as Class
36+
import Node.Buffer.Immutable (ImmutableBuffer)
1137
import Node.Buffer.Internal as Internal
1238
import Node.Buffer.Types (BufferValueType(..), Octet, Offset) as TypesExports
39+
import Node.Buffer.Types (BufferValueType)
40+
import Node.Encoding (Encoding)
1341

1442
-- | A reference to a mutable buffer for use with `Effect`
1543
foreign import data Buffer :: Type
1644

1745
instance mutableBufferEffect :: MutableBuffer Buffer Effect where
18-
create = Internal.create
19-
freeze = Internal.copyAll
20-
unsafeFreeze = Internal.unsafeFreeze
21-
thaw = Internal.copyAll
22-
unsafeThaw = Internal.unsafeThaw
23-
fromArray = Internal.fromArray
24-
fromString = Internal.fromString
25-
fromArrayBuffer = Internal.fromArrayBuffer
26-
toArrayBuffer = Internal.toArrayBuffer
27-
read = Internal.read
28-
readString = Internal.readString
29-
toString = Internal.toString
30-
write = Internal.write
31-
writeString = Internal.writeString
32-
toArray = Internal.toArray
33-
getAtOffset = Internal.getAtOffset
34-
setAtOffset = Internal.setAtOffset
35-
slice = Internal.slice
36-
size = Internal.size
37-
concat = Internal.concat
38-
concat' = Internal.concat'
39-
copy = Internal.copy
40-
fill = Internal.fill
46+
create = create
47+
freeze = freeze
48+
unsafeFreeze = unsafeFreeze
49+
thaw = thaw
50+
unsafeThaw = unsafeThaw
51+
fromArray = fromArray
52+
fromString = fromString
53+
fromArrayBuffer = fromArrayBuffer
54+
toArrayBuffer = toArrayBuffer
55+
read = read
56+
readString = readString
57+
toString = toString
58+
write = write
59+
writeString = writeString
60+
toArray = toArray
61+
getAtOffset = getAtOffset
62+
setAtOffset = setAtOffset
63+
slice = slice
64+
size = size
65+
concat = concat
66+
concat' = concat'
67+
copy = copy
68+
fill = fill
69+
70+
create :: Int -> Effect Buffer
71+
create = Internal.create
72+
73+
freeze :: Buffer -> Effect ImmutableBuffer
74+
freeze = Internal.copyAll
75+
76+
unsafeFreeze :: Buffer -> Effect ImmutableBuffer
77+
unsafeFreeze = Internal.unsafeFreeze
78+
79+
thaw :: ImmutableBuffer -> Effect Buffer
80+
thaw = Internal.copyAll
81+
82+
unsafeThaw :: ImmutableBuffer -> Effect Buffer
83+
unsafeThaw = Internal.unsafeThaw
84+
85+
fromArray :: Array Int -> Effect Buffer
86+
fromArray = Internal.fromArray
87+
88+
fromString :: String -> Encoding -> Effect Buffer
89+
fromString = Internal.fromString
90+
91+
fromArrayBuffer :: ArrayBuffer -> Effect Buffer
92+
fromArrayBuffer = Internal.fromArrayBuffer
93+
94+
toArrayBuffer :: Buffer -> Effect ArrayBuffer
95+
toArrayBuffer = Internal.toArrayBuffer
96+
97+
read :: BufferValueType -> Int -> Buffer -> Effect Number
98+
read = Internal.read
99+
100+
readString :: Encoding -> Int -> Int -> Buffer -> Effect String
101+
readString = Internal.readString
102+
103+
toString :: Encoding -> Buffer -> Effect String
104+
toString = Internal.toString
105+
106+
write :: BufferValueType -> Number -> Int -> Buffer -> Effect Unit
107+
write = Internal.write
108+
109+
writeString :: Encoding -> Int -> Int -> String -> Buffer -> Effect Int
110+
writeString = Internal.writeString
111+
112+
toArray :: Buffer -> Effect (Array Int)
113+
toArray = Internal.toArray
114+
115+
getAtOffset :: Int -> Buffer -> Effect (Maybe Int)
116+
getAtOffset = Internal.getAtOffset
117+
118+
setAtOffset :: Int -> Int -> Buffer -> Effect Unit
119+
setAtOffset = Internal.setAtOffset
120+
121+
slice :: Int -> Int -> Buffer -> Buffer
122+
slice = Internal.slice
123+
124+
size :: Buffer -> Effect Int
125+
size = Internal.size
126+
127+
concat :: Array Buffer -> Effect Buffer
128+
concat = Internal.concat
129+
130+
concat' :: Array Buffer -> Int -> Effect Buffer
131+
concat' = Internal.concat'
132+
133+
copy :: Int -> Int -> Buffer -> Int -> Buffer -> Effect Int
134+
copy = Internal.copy
135+
136+
fill :: Int -> Int -> Int -> Buffer -> Effect Unit
137+
fill = Internal.fill

‎src/Node/Buffer/ST.purs

Lines changed: 120 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,42 @@
11
module Node.Buffer.ST
22
( STBuffer
33
, run
4+
, create
5+
, freeze
6+
, unsafeFreeze
7+
, thaw
8+
, unsafeThaw
9+
, fromArray
10+
, fromString
11+
, fromArrayBuffer
12+
, toArrayBuffer
13+
, read
14+
, readString
15+
, toString
16+
, write
17+
, writeString
18+
, toArray
19+
, getAtOffset
20+
, setAtOffset
21+
, slice
22+
, size
23+
, concat
24+
, concat'
25+
, copy
26+
, fill
427
) where
528

629
import Prelude
730

831
import Control.Monad.ST (ST, Region)
932
import Control.Monad.ST as ST
10-
import Node.Buffer.Class (class MutableBuffer, unsafeFreeze)
33+
import Data.ArrayBuffer.Types (ArrayBuffer)
34+
import Data.Maybe (Maybe)
35+
import Node.Buffer (BufferValueType)
36+
import Node.Buffer.Class (class MutableBuffer)
1137
import Node.Buffer.Immutable (ImmutableBuffer)
1238
import Node.Buffer.Internal as Internal
39+
import Node.Encoding (Encoding)
1340

1441
-- | A reference to a mutable buffer for use with `ST`
1542
-- |
@@ -22,26 +49,95 @@ run :: (forall h. ST h (STBuffer h)) -> ImmutableBuffer
2249
run st = ST.run (st >>= unsafeFreeze)
2350

2451
instance mutableBufferST :: MutableBuffer (STBuffer h) (ST h) where
25-
create = Internal.create
26-
freeze = Internal.copyAll
27-
unsafeFreeze = Internal.unsafeFreeze
28-
thaw = Internal.copyAll
29-
unsafeThaw = Internal.unsafeThaw
30-
fromArray = Internal.fromArray
31-
fromString = Internal.fromString
32-
fromArrayBuffer = Internal.fromArrayBuffer
33-
toArrayBuffer = Internal.toArrayBuffer
34-
read = Internal.read
35-
readString = Internal.readString
36-
toString = Internal.toString
37-
write = Internal.write
38-
writeString = Internal.writeString
39-
toArray = Internal.toArray
40-
getAtOffset = Internal.getAtOffset
41-
setAtOffset = Internal.setAtOffset
42-
slice = Internal.slice
43-
size = Internal.size
44-
concat = Internal.concat
45-
concat' = Internal.concat'
46-
copy = Internal.copy
47-
fill = Internal.fill
52+
create = create
53+
freeze = freeze
54+
unsafeFreeze = unsafeFreeze
55+
thaw = thaw
56+
unsafeThaw = unsafeThaw
57+
fromArray = fromArray
58+
fromString = fromString
59+
fromArrayBuffer = fromArrayBuffer
60+
toArrayBuffer = toArrayBuffer
61+
read = read
62+
readString = readString
63+
toString = toString
64+
write = write
65+
writeString = writeString
66+
toArray = toArray
67+
getAtOffset = getAtOffset
68+
setAtOffset = setAtOffset
69+
slice = slice
70+
size = size
71+
concat = concat
72+
concat' = concat'
73+
copy = copy
74+
fill = fill
75+
76+
create :: forall h. Int -> ST h (STBuffer h)
77+
create = Internal.create
78+
79+
freeze :: forall h. STBuffer h -> ST h ImmutableBuffer
80+
freeze = Internal.copyAll
81+
82+
unsafeFreeze :: forall h. STBuffer h -> ST h ImmutableBuffer
83+
unsafeFreeze = Internal.unsafeFreeze
84+
85+
thaw :: forall h. ImmutableBuffer -> ST h (STBuffer h)
86+
thaw = Internal.copyAll
87+
88+
unsafeThaw :: forall h. ImmutableBuffer -> ST h (STBuffer h)
89+
unsafeThaw = Internal.unsafeThaw
90+
91+
fromArray :: forall h. Array Int -> ST h (STBuffer h)
92+
fromArray = Internal.fromArray
93+
94+
fromString :: forall h. String -> Encoding -> ST h (STBuffer h)
95+
fromString = Internal.fromString
96+
97+
fromArrayBuffer :: forall h. ArrayBuffer -> ST h (STBuffer h)
98+
fromArrayBuffer = Internal.fromArrayBuffer
99+
100+
toArrayBuffer :: forall h. STBuffer h -> ST h ArrayBuffer
101+
toArrayBuffer = Internal.toArrayBuffer
102+
103+
read :: forall h. BufferValueType -> Int -> STBuffer h -> ST h Number
104+
read = Internal.read
105+
106+
readString :: forall h. Encoding -> Int -> Int -> STBuffer h -> ST h String
107+
readString = Internal.readString
108+
109+
toString :: forall h. Encoding -> STBuffer h -> ST h String
110+
toString = Internal.toString
111+
112+
write :: forall h. BufferValueType -> Number -> Int -> STBuffer h -> ST h Unit
113+
write = Internal.write
114+
115+
writeString :: forall h. Encoding -> Int -> Int -> String -> STBuffer h -> ST h Int
116+
writeString = Internal.writeString
117+
118+
toArray :: forall h. STBuffer h -> ST h (Array Int)
119+
toArray = Internal.toArray
120+
121+
getAtOffset :: forall h. Int -> STBuffer h -> ST h (Maybe Int)
122+
getAtOffset = Internal.getAtOffset
123+
124+
setAtOffset :: forall h. Int -> Int -> STBuffer h -> ST h Unit
125+
setAtOffset = Internal.setAtOffset
126+
127+
slice :: forall h. Int -> Int -> STBuffer h -> STBuffer h
128+
slice = Internal.slice
129+
130+
size :: forall h. STBuffer h -> ST h Int
131+
size = Internal.size
132+
133+
concat :: forall h. Array (STBuffer h) -> ST h (STBuffer h)
134+
concat = Internal.concat
135+
136+
concat' :: forall h. Array (STBuffer h) -> Int -> ST h (STBuffer h)
137+
concat' = Internal.concat'
138+
139+
copy :: forall h. Int -> Int -> STBuffer h -> Int -> STBuffer h -> ST h Int
140+
copy = Internal.copy
141+
142+
fill :: forall h. Int -> Int -> Int -> STBuffer h -> ST h Unit
143+
fill = Internal.fill

‎test/Test/Node/Buffer/Class.purs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import Data.Maybe (Maybe(..))
77
import Data.Traversable (traverse)
88
import Effect (Effect)
99
import Effect.Console (log)
10-
import Node.Buffer (class MutableBuffer, BufferValueType(..), concat', copy, create, fill, freeze, fromArray, fromArrayBuffer, fromString, getAtOffset, read, readString, setAtOffset, slice, thaw, toArray, toArrayBuffer, toString, write)
10+
import Node.Buffer.Class (class MutableBuffer, concat', copy, create, fill, freeze, fromArray, fromArrayBuffer, fromString, getAtOffset, read, readString, setAtOffset, slice, thaw, toArray, toArrayBuffer, toString, write)
11+
import Node.Buffer (BufferValueType(..))
1112
import Node.Buffer.Immutable as Immutable
1213
import Node.Encoding (Encoding(..))
1314
import Test.Assert (assertEqual)

‎test/Test/Node/Buffer/ST.purs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ module Test.Node.Buffer.ST (test) where
22

33
import Prelude
44

5-
import Control.Monad.ST (run) as ST
65
import Effect (Effect)
76
import Effect.Console (log)
87
import Node.Buffer.Class (create)

0 commit comments

Comments
 (0)
Please sign in to comment.