Compare commits

..

9 Commits

Author SHA1 Message Date
George Thomas
0c70b2a3f7 maybe/optional example 2026-03-25 13:13:25 +00:00
George Thomas
c735ffb4f3 minor refactor for consistency (maybe we should go the other way given sumSlice...) 2026-03-25 13:13:25 +00:00
George Thomas
8847012bbc vector/slice example 2026-03-25 13:13:25 +00:00
George Thomas
9417c06574 pass by (immutable) reference for all non-primitive types 2026-03-25 13:13:25 +00:00
George Thomas
32de67723b dedup base dep 2026-03-25 13:13:25 +00:00
George Thomas
c32606904f follow-up simplification 2026-03-25 13:13:25 +00:00
George Thomas
82c9262e91 argh, unrelated breaking change, and bad names 2026-03-25 13:13:25 +00:00
George Thomas
aaaf02b783 use upstream fix to avoid header patching hack... 2026-03-25 13:13:25 +00:00
George Thomas
621a44caa9 stuff from Yuri...
things I've changed from the PR:
- dropped legacy (i.e. non-flake) compat stuff, which turns out to account for most of the diff
- dropped `packages.garnet` since it doesn't work with `nix build .#garnet`
- back to using Rust-extended packages everywhere, which _seems_ fine
the rest is just re-inlining things and other refactors

note that changes we keep are essentially:
- not using Crane's extended packages everywhere
- bumping `nix-haskell` to avoid shell hook workaround
- various changes in how we call `nix-haskell`
- using `libCgarnet_rs` name, which Cabal expects
- adding proper non-dev-shell targets, so that e.g. `nix run` works

stuff we should still take a look at:
- seems a bit weird that `garnet-rs` arg to `project.nix` was always same (and therefore now we always pass the ) - might be a mistake, and we're supposed to be using local for local build?
- similar `libCgarnet_rs.a` logic appears in three places - see if we can deduplicate to some extent somehow
- I haven't even checked all steps are necessary
2026-03-25 13:13:17 +00:00
10 changed files with 781 additions and 86 deletions

2
build
View File

@ -5,6 +5,6 @@ cargo build --manifest-path ./rust/Cargo.toml
BUNDLED_LIB_DIR=$(cabal list-bin . | sed -e 's=x/garnet/build/garnet/garnet=build=g')
mkdir -p $BUNDLED_LIB_DIR
ln -sf $(pwd)/rust/target/debug/libgarnet_rs.a $BUNDLED_LIB_DIR
ln -sf $(pwd)/rust/target/debug/libgarnet_rs.a $BUNDLED_LIB_DIR/libCgarnet_rs.a
cabal build

View File

@ -1,6 +1,8 @@
module Main (main) where
import Data.Vector.Storable qualified as V
import GarnetRs.Wrapped
import System.IO
main :: IO ()
main = do
@ -11,3 +13,6 @@ main = do
helloShape $ Rectangle 10.0 5.0
putStrLn $ "3 + 4 = " <> show (add 3 4)
putStrLn $ "Tree sum: " <> show (sumTree (Fork (Fork (Leaf 1) (Fork (Leaf 2) (Leaf 3))) (Leaf 4)))
putStrLn $ "Slice sum: " <> show (sumSlice $ V.fromList [0 .. 5])
putStrLn "Nothing." >> printOptional Nothing
putStr "Something: " >> hFlush stdout >> printOptional (Just 67)

707
flake.lock generated
View File

@ -1,12 +1,95 @@
{
"nodes": {
"HTTP": {
"flake": false,
"locked": {
"lastModified": 1451647621,
"narHash": "sha256-oHIyw3x0iKBexEo49YeUDV1k74ZtyYKGR2gNJXXRxts=",
"owner": "phadej",
"repo": "HTTP",
"rev": "9bc0996d412fef1787449d841277ef663ad9a915",
"type": "github"
},
"original": {
"owner": "phadej",
"repo": "HTTP",
"type": "github"
}
},
"cabal-32": {
"flake": false,
"locked": {
"lastModified": 1603716527,
"narHash": "sha256-X0TFfdD4KZpwl0Zr6x+PLxUt/VyKQfX7ylXHdmZIL+w=",
"owner": "haskell",
"repo": "cabal",
"rev": "48bf10787e27364730dd37a42b603cee8d6af7ee",
"type": "github"
},
"original": {
"owner": "haskell",
"ref": "3.2",
"repo": "cabal",
"type": "github"
}
},
"cabal-34": {
"flake": false,
"locked": {
"lastModified": 1645834128,
"narHash": "sha256-wG3d+dOt14z8+ydz4SL7pwGfe7SiimxcD/LOuPCV6xM=",
"owner": "haskell",
"repo": "cabal",
"rev": "5ff598c67f53f7c4f48e31d722ba37172230c462",
"type": "github"
},
"original": {
"owner": "haskell",
"ref": "3.4",
"repo": "cabal",
"type": "github"
}
},
"cabal-36": {
"flake": false,
"locked": {
"lastModified": 1669081697,
"narHash": "sha256-I5or+V7LZvMxfbYgZATU4awzkicBwwok4mVoje+sGmU=",
"owner": "haskell",
"repo": "cabal",
"rev": "8fd619e33d34924a94e691c5fea2c42f0fc7f144",
"type": "github"
},
"original": {
"owner": "haskell",
"ref": "3.6",
"repo": "cabal",
"type": "github"
}
},
"cardano-shell": {
"flake": false,
"locked": {
"lastModified": 1608537748,
"narHash": "sha256-PulY1GfiMgKVnBci3ex4ptk2UNYMXqGjJOxcPy2KYT4=",
"owner": "input-output-hk",
"repo": "cardano-shell",
"rev": "9392c75087cb9a3d453998f4230930dea3a95725",
"type": "github"
},
"original": {
"owner": "input-output-hk",
"repo": "cardano-shell",
"type": "github"
}
},
"crane": {
"locked": {
"lastModified": 1771438068,
"narHash": "sha256-nGBbXvEZVe/egCPVPFcu89RFtd8Rf6J+4RFoVCFec0A=",
"lastModified": 1774313767,
"narHash": "sha256-hy0XTQND6avzGEUFrJtYBBpFa/POiiaGBr2vpU6Y9tY=",
"owner": "ipetkov",
"repo": "crane",
"rev": "b5090e53e9d68c523a4bb9ad42b4737ee6747597",
"rev": "3d9df76e29656c679c744968b17fbaf28f0e923d",
"type": "github"
},
"original": {
@ -15,6 +98,38 @@
"type": "github"
}
},
"flake-compat": {
"locked": {
"lastModified": 1767039857,
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
"owner": "NixOS",
"repo": "flake-compat",
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "flake-compat",
"type": "github"
}
},
"flake-compat_2": {
"flake": false,
"locked": {
"lastModified": 1672831974,
"narHash": "sha256-z9k3MfslLjWQfnjBtEtJZdq3H7kyi2kQtUThfTgdRk0=",
"owner": "input-output-hk",
"repo": "flake-compat",
"rev": "45f2638735f8cdc40fe302742b79f248d23eb368",
"type": "github"
},
"original": {
"owner": "input-output-hk",
"ref": "hkm/gitlab-fix",
"repo": "flake-compat",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
@ -33,6 +148,349 @@
"type": "github"
}
},
"hackage": {
"flake": false,
"locked": {
"lastModified": 1770685064,
"narHash": "sha256-e2G/GFzIdTXosxq+3Z0OXbSUmXy9tDbZZ6wsmfy7Hf8=",
"owner": "input-output-hk",
"repo": "hackage.nix",
"rev": "84628a8e4b5d580766d49d62a5e2e065cbb8604e",
"type": "github"
},
"original": {
"owner": "input-output-hk",
"repo": "hackage.nix",
"type": "github"
}
},
"hackage-for-stackage": {
"flake": false,
"locked": {
"lastModified": 1770683900,
"narHash": "sha256-03cshwLY80e5jBUgNBmoFoiH1e3VvhAX+1ME4NVt5g4=",
"owner": "input-output-hk",
"repo": "hackage.nix",
"rev": "c7d9e737cd1e07136982e0df0f9aa12391e2c883",
"type": "github"
},
"original": {
"owner": "input-output-hk",
"ref": "for-stackage",
"repo": "hackage.nix",
"type": "github"
}
},
"hackage-internal": {
"flake": false,
"locked": {
"lastModified": 1750307553,
"narHash": "sha256-iiafNoeLHwlSLQTyvy8nPe2t6g5AV4PPcpMeH/2/DLs=",
"owner": "input-output-hk",
"repo": "hackage.nix",
"rev": "f7867baa8817fab296528f4a4ec39d1c7c4da4f3",
"type": "github"
},
"original": {
"owner": "input-output-hk",
"repo": "hackage.nix",
"type": "github"
}
},
"haskell-nix": {
"inputs": {
"HTTP": "HTTP",
"cabal-32": "cabal-32",
"cabal-34": "cabal-34",
"cabal-36": "cabal-36",
"cardano-shell": "cardano-shell",
"flake-compat": "flake-compat_2",
"hackage": "hackage",
"hackage-for-stackage": "hackage-for-stackage",
"hackage-internal": "hackage-internal",
"hls": "hls",
"hls-1.10": "hls-1.10",
"hls-2.0": "hls-2.0",
"hls-2.10": "hls-2.10",
"hls-2.11": "hls-2.11",
"hls-2.12": "hls-2.12",
"hls-2.2": "hls-2.2",
"hls-2.3": "hls-2.3",
"hls-2.4": "hls-2.4",
"hls-2.5": "hls-2.5",
"hls-2.6": "hls-2.6",
"hls-2.7": "hls-2.7",
"hls-2.8": "hls-2.8",
"hls-2.9": "hls-2.9",
"hpc-coveralls": "hpc-coveralls",
"iserv-proxy": "iserv-proxy",
"nixpkgs": [
"nix-haskell",
"haskell-nix",
"nixpkgs-unstable"
],
"nixpkgs-2305": "nixpkgs-2305",
"nixpkgs-2311": "nixpkgs-2311",
"nixpkgs-2405": "nixpkgs-2405",
"nixpkgs-2411": "nixpkgs-2411",
"nixpkgs-2505": "nixpkgs-2505",
"nixpkgs-2511": "nixpkgs-2511",
"nixpkgs-unstable": "nixpkgs-unstable",
"old-ghc-nix": "old-ghc-nix",
"stackage": "stackage"
},
"locked": {
"lastModified": 1773942398,
"narHash": "sha256-VFUyPaWqXN357StToBRFbOCZAP4n8iCfEh2ZV1dNH88=",
"owner": "ymeister",
"repo": "haskell.nix",
"rev": "9fa7c11202e16c8cd2743deed4d811da1cfb2e51",
"type": "github"
},
"original": {
"owner": "ymeister",
"repo": "haskell.nix",
"rev": "9fa7c11202e16c8cd2743deed4d811da1cfb2e51",
"type": "github"
}
},
"hls": {
"flake": false,
"locked": {
"lastModified": 1741604408,
"narHash": "sha256-tuq3+Ip70yu89GswZ7DSINBpwRprnWnl6xDYnS4GOsc=",
"owner": "haskell",
"repo": "haskell-language-server",
"rev": "682d6894c94087da5e566771f25311c47e145359",
"type": "github"
},
"original": {
"owner": "haskell",
"repo": "haskell-language-server",
"type": "github"
}
},
"hls-1.10": {
"flake": false,
"locked": {
"lastModified": 1680000865,
"narHash": "sha256-rc7iiUAcrHxwRM/s0ErEsSPxOR3u8t7DvFeWlMycWgo=",
"owner": "haskell",
"repo": "haskell-language-server",
"rev": "b08691db779f7a35ff322b71e72a12f6e3376fd9",
"type": "github"
},
"original": {
"owner": "haskell",
"ref": "1.10.0.0",
"repo": "haskell-language-server",
"type": "github"
}
},
"hls-2.0": {
"flake": false,
"locked": {
"lastModified": 1687698105,
"narHash": "sha256-OHXlgRzs/kuJH8q7Sxh507H+0Rb8b7VOiPAjcY9sM1k=",
"owner": "haskell",
"repo": "haskell-language-server",
"rev": "783905f211ac63edf982dd1889c671653327e441",
"type": "github"
},
"original": {
"owner": "haskell",
"ref": "2.0.0.1",
"repo": "haskell-language-server",
"type": "github"
}
},
"hls-2.10": {
"flake": false,
"locked": {
"lastModified": 1743069404,
"narHash": "sha256-q4kDFyJDDeoGqfEtrZRx4iqMVEC2MOzCToWsFY+TOzY=",
"owner": "haskell",
"repo": "haskell-language-server",
"rev": "2318c61db3a01e03700bd4b05665662929b7fe8b",
"type": "github"
},
"original": {
"owner": "haskell",
"ref": "2.10.0.0",
"repo": "haskell-language-server",
"type": "github"
}
},
"hls-2.11": {
"flake": false,
"locked": {
"lastModified": 1747306193,
"narHash": "sha256-/MmtpF8+FyQlwfKHqHK05BdsxC9LHV70d/FiMM7pzBM=",
"owner": "haskell",
"repo": "haskell-language-server",
"rev": "46ef4523ea4949f47f6d2752476239f1c6d806fe",
"type": "github"
},
"original": {
"owner": "haskell",
"ref": "2.11.0.0",
"repo": "haskell-language-server",
"type": "github"
}
},
"hls-2.12": {
"flake": false,
"locked": {
"lastModified": 1758709460,
"narHash": "sha256-xkI8MIIVEVARskfWbGAgP5sHG/lyeKnkm0LIOJ19X5w=",
"owner": "haskell",
"repo": "haskell-language-server",
"rev": "7d983de4fa7ff54369f6dd31444bdb9869aec83e",
"type": "github"
},
"original": {
"owner": "haskell",
"ref": "2.12.0.0",
"repo": "haskell-language-server",
"type": "github"
}
},
"hls-2.2": {
"flake": false,
"locked": {
"lastModified": 1693064058,
"narHash": "sha256-8DGIyz5GjuCFmohY6Fa79hHA/p1iIqubfJUTGQElbNk=",
"owner": "haskell",
"repo": "haskell-language-server",
"rev": "b30f4b6cf5822f3112c35d14a0cba51f3fe23b85",
"type": "github"
},
"original": {
"owner": "haskell",
"ref": "2.2.0.0",
"repo": "haskell-language-server",
"type": "github"
}
},
"hls-2.3": {
"flake": false,
"locked": {
"lastModified": 1695910642,
"narHash": "sha256-tR58doOs3DncFehHwCLczJgntyG/zlsSd7DgDgMPOkI=",
"owner": "haskell",
"repo": "haskell-language-server",
"rev": "458ccdb55c9ea22cd5d13ec3051aaefb295321be",
"type": "github"
},
"original": {
"owner": "haskell",
"ref": "2.3.0.0",
"repo": "haskell-language-server",
"type": "github"
}
},
"hls-2.4": {
"flake": false,
"locked": {
"lastModified": 1699862708,
"narHash": "sha256-YHXSkdz53zd0fYGIYOgLt6HrA0eaRJi9mXVqDgmvrjk=",
"owner": "haskell",
"repo": "haskell-language-server",
"rev": "54507ef7e85fa8e9d0eb9a669832a3287ffccd57",
"type": "github"
},
"original": {
"owner": "haskell",
"ref": "2.4.0.1",
"repo": "haskell-language-server",
"type": "github"
}
},
"hls-2.5": {
"flake": false,
"locked": {
"lastModified": 1701080174,
"narHash": "sha256-fyiR9TaHGJIIR0UmcCb73Xv9TJq3ht2ioxQ2mT7kVdc=",
"owner": "haskell",
"repo": "haskell-language-server",
"rev": "27f8c3d3892e38edaef5bea3870161815c4d014c",
"type": "github"
},
"original": {
"owner": "haskell",
"ref": "2.5.0.0",
"repo": "haskell-language-server",
"type": "github"
}
},
"hls-2.6": {
"flake": false,
"locked": {
"lastModified": 1705325287,
"narHash": "sha256-+P87oLdlPyMw8Mgoul7HMWdEvWP/fNlo8jyNtwME8E8=",
"owner": "haskell",
"repo": "haskell-language-server",
"rev": "6e0b342fa0327e628610f2711f8c3e4eaaa08b1e",
"type": "github"
},
"original": {
"owner": "haskell",
"ref": "2.6.0.0",
"repo": "haskell-language-server",
"type": "github"
}
},
"hls-2.7": {
"flake": false,
"locked": {
"lastModified": 1708965829,
"narHash": "sha256-LfJ+TBcBFq/XKoiNI7pc4VoHg4WmuzsFxYJ3Fu+Jf+M=",
"owner": "haskell",
"repo": "haskell-language-server",
"rev": "50322b0a4aefb27adc5ec42f5055aaa8f8e38001",
"type": "github"
},
"original": {
"owner": "haskell",
"ref": "2.7.0.0",
"repo": "haskell-language-server",
"type": "github"
}
},
"hls-2.8": {
"flake": false,
"locked": {
"lastModified": 1715153580,
"narHash": "sha256-Vi/iUt2pWyUJlo9VrYgTcbRviWE0cFO6rmGi9rmALw0=",
"owner": "haskell",
"repo": "haskell-language-server",
"rev": "dd1be1beb16700de59e0d6801957290bcf956a0a",
"type": "github"
},
"original": {
"owner": "haskell",
"ref": "2.8.0.0",
"repo": "haskell-language-server",
"type": "github"
}
},
"hls-2.9": {
"flake": false,
"locked": {
"lastModified": 1719993701,
"narHash": "sha256-wy348++MiMm/xwtI9M3vVpqj2qfGgnDcZIGXw8sF1sA=",
"owner": "haskell",
"repo": "haskell-language-server",
"rev": "90319a7e62ab93ab65a95f8f2bcf537e34dae76a",
"type": "github"
},
"original": {
"owner": "haskell",
"ref": "2.9.0.1",
"repo": "haskell-language-server",
"type": "github"
}
},
"hls-src": {
"flake": false,
"locked": {
@ -50,50 +508,84 @@
"type": "github"
}
},
"hpc-coveralls": {
"flake": false,
"locked": {
"lastModified": 1607498076,
"narHash": "sha256-8uqsEtivphgZWYeUo5RDUhp6bO9j2vaaProQxHBltQk=",
"owner": "sevanspowell",
"repo": "hpc-coveralls",
"rev": "14df0f7d229f4cd2e79f8eabb1a740097fdfa430",
"type": "github"
},
"original": {
"owner": "sevanspowell",
"repo": "hpc-coveralls",
"type": "github"
}
},
"hs-bindgen-src": {
"flake": false,
"locked": {
"lastModified": 1773399083,
"narHash": "sha256-oF6E1/zRZ4iiZs9QjtQMvHnLMfq/W6CXOX44QbDGYXs=",
"lastModified": 1774379170,
"narHash": "sha256-lZV6IdCBf8uCt21qB5mfgLaP9CNgho/HsqjvkulDR2Q=",
"owner": "well-typed",
"repo": "hs-bindgen",
"rev": "6ca94188abd756a1fb4dd8a4037de3fa7dca0765",
"rev": "4b6febb5cc6196835bd2890a3ab27a88dab1806b",
"type": "github"
},
"original": {
"owner": "well-typed",
"repo": "hs-bindgen",
"rev": "6ca94188abd756a1fb4dd8a4037de3fa7dca0765",
"type": "github"
}
},
"iserv-proxy": {
"flake": false,
"locked": {
"lastModified": 1770174258,
"narHash": "sha256-x6QYupvHZM7rRpVO4AIC5gUWFprFQ59A95FPC7/Owjg=",
"owner": "stable-haskell",
"repo": "iserv-proxy",
"rev": "91ef7ffdeedfb141a4d69dcf9e550abe3e1160c6",
"type": "github"
},
"original": {
"owner": "stable-haskell",
"ref": "iserv-syms",
"repo": "iserv-proxy",
"type": "github"
}
},
"libclang-src": {
"flake": false,
"locked": {
"lastModified": 1773221966,
"narHash": "sha256-VPG7jKdq2g/Hwf5cPiy4coAvLULxDeA4KHCVkNSSs5w=",
"lastModified": 1774018529,
"narHash": "sha256-Bo5wvityXKCmlnrobtI9WkA1maR7sfkDXo1VOZvrPLk=",
"owner": "well-typed",
"repo": "libclang",
"rev": "d6e482df49b88375cf3075928a78ee86c2a068d4",
"rev": "83387d72a8dfae9f75d27db6b32ea37afab06268",
"type": "github"
},
"original": {
"owner": "well-typed",
"repo": "libclang",
"rev": "d6e482df49b88375cf3075928a78ee86c2a068d4",
"type": "github"
}
},
"nix-haskell": {
"inputs": {
"nixpkgs": "nixpkgs"
"flake-compat": "flake-compat",
"haskell-nix": "haskell-nix",
"nixpkgs": "nixpkgs",
"reflex-platform": "reflex-platform"
},
"locked": {
"lastModified": 1774311314,
"narHash": "sha256-sxoNFlpTaBnnQerzQ2LTByXPpR37M4pHnhZmzq+9440=",
"lastModified": 1774408168,
"narHash": "sha256-do26Ik50yH8NYSxuhwzBwNKsxIN88GoovwioWPvCpJU=",
"owner": "reflex-frp",
"repo": "nix-haskell",
"rev": "85d89f1cc2f591ff6be35e1f112c8ee912fba7bb",
"rev": "d6a3bb8f96ff35fd0ae2a0d64f40b584c92aa493",
"type": "github"
},
"original": {
@ -104,16 +596,164 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1773840656,
"narHash": "sha256-9tpvMGFteZnd3gRQZFlRCohVpqooygFuy9yjuyRL2C0=",
"lastModified": 1769089682,
"narHash": "sha256-9yA/LIuAVQq0lXelrZPjLuLVuZdm03p8tfmHhnDIkms=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "9cf7092bdd603554bd8b63c216e8943cf9b12512",
"rev": "078d69f03934859a181e81ba987c2bb033eebfc5",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "078d69f03934859a181e81ba987c2bb033eebfc5",
"type": "github"
}
},
"nixpkgs-2305": {
"locked": {
"lastModified": 1705033721,
"narHash": "sha256-K5eJHmL1/kev6WuqyqqbS1cdNnSidIZ3jeqJ7GbrYnQ=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a1982c92d8980a0114372973cbdfe0a307f1bdea",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-23.05-darwin",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-2311": {
"locked": {
"lastModified": 1719957072,
"narHash": "sha256-gvFhEf5nszouwLAkT9nWsDzocUTqLWHuL++dvNjMp9I=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "7144d6241f02d171d25fba3edeaf15e0f2592105",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-23.11-darwin",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-2405": {
"locked": {
"lastModified": 1735564410,
"narHash": "sha256-HB/FA0+1gpSs8+/boEavrGJH+Eq08/R2wWNph1sM1Dg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "1e7a8f391f1a490460760065fa0630b5520f9cf8",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-24.05-darwin",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-2411": {
"locked": {
"lastModified": 1751290243,
"narHash": "sha256-kNf+obkpJZWar7HZymXZbW+Rlk3HTEIMlpc6FCNz0Ds=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "5ab036a8d97cb9476fbe81b09076e6e91d15e1b6",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-24.11-darwin",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-2505": {
"locked": {
"lastModified": 1764560356,
"narHash": "sha256-M5aFEFPppI4UhdOxwdmceJ9bDJC4T6C6CzCK1E2FZyo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "6c8f0cca84510cc79e09ea99a299c9bc17d03cb6",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-25.05-darwin",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-2511": {
"locked": {
"lastModified": 1764572236,
"narHash": "sha256-hLp6T/vKdrBQolpbN3EhJOKTXZYxJZPzpnoZz+fEGlE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b0924ea1889b366de6bb0018a9db70b2c43a15f8",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-25.11-darwin",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1764587062,
"narHash": "sha256-hdFa0TAVQAQLDF31cEW3enWmBP+b592OvHs6WVe3D8k=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c1cb7d097cb250f6e1904aacd5f2ba5ffd8a49ce",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"old-ghc-nix": {
"flake": false,
"locked": {
"lastModified": 1631092763,
"narHash": "sha256-sIKgO+z7tj4lw3u6oBZxqIhDrzSkvpHtv0Kki+lh9Fg=",
"owner": "angerman",
"repo": "old-ghc-nix",
"rev": "af48a7a7353e418119b6dfe3cd1463a657f342b8",
"type": "github"
},
"original": {
"owner": "angerman",
"ref": "master",
"repo": "old-ghc-nix",
"type": "github"
}
},
"reflex-platform": {
"flake": false,
"locked": {
"lastModified": 1760924715,
"narHash": "sha256-pUraGts8qa3R9jQqaVXevkC+nM07B8oF+LGF4xsyiJU=",
"owner": "reflex-frp",
"repo": "reflex-platform",
"rev": "4482ecb04c5939ac77c26d769d149dee12051a13",
"type": "github"
},
"original": {
"owner": "reflex-frp",
"repo": "reflex-platform",
"rev": "4482ecb04c5939ac77c26d769d149dee12051a13",
"type": "github"
}
},
"root": {
@ -124,22 +764,25 @@
"hs-bindgen-src": "hs-bindgen-src",
"libclang-src": "libclang-src",
"nix-haskell": "nix-haskell",
"nixpkgs": [
"nix-haskell",
"nixpkgs"
],
"rust-overlay": "rust-overlay"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": [
"nix-haskell",
"nixpkgs"
]
},
"locked": {
"lastModified": 1771470520,
"narHash": "sha256-PvytHcaYN5cPUll7FB70mXv1rRsIBRmu47fFfq3haxA=",
"lastModified": 1774408260,
"narHash": "sha256-Jn9d9r85dmf3gTMnSRt6t+DP2nQ5uJns/MMXg2FpzfM=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "a1d4cc1f264c45d3745af0d2ca5e59d460e58777",
"rev": "d6471ee5a8f470251e6e5b83a20a182eb6c46c9b",
"type": "github"
},
"original": {
@ -148,6 +791,22 @@
"type": "github"
}
},
"stackage": {
"flake": false,
"locked": {
"lastModified": 1770596307,
"narHash": "sha256-88b6YzeBaQr9ihSWAOxVGewCDfROKt2rOIHymadu3DI=",
"owner": "input-output-hk",
"repo": "stackage.nix",
"rev": "ff21e9b6a976faed56963ae5fa5d5396dc48ea63",
"type": "github"
},
"original": {
"owner": "input-output-hk",
"repo": "stackage.nix",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,

View File

@ -1,38 +1,53 @@
{
inputs = {
nix-haskell.url = "github:reflex-frp/nix-haskell";
nixpkgs.follows = "nix-haskell/nixpkgs";
hls-src = { url = "github:haskell/haskell-language-server/2.13.0.0"; flake = false; };
hs-bindgen-src = { url = "github:well-typed/hs-bindgen/6ca94188abd756a1fb4dd8a4037de3fa7dca0765"; flake = false; };
libclang-src = { url = "github:well-typed/libclang/d6e482df49b88375cf3075928a78ee86c2a068d4"; flake = false; };
hs-bindgen-src = { url = "github:well-typed/hs-bindgen"; flake = false; };
libclang-src = { url = "github:well-typed/libclang"; flake = false; };
flake-utils.url = "github:numtide/flake-utils";
crane.url = "github:ipetkov/crane";
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nix-haskell/nixpkgs";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
inputs@{ nix-haskell, ... }:
inputs.flake-utils.lib.eachSystem [ "x86_64-linux" ] (system:
let
lib = nix-haskell.lib.${system};
project = lib.nix-haskell (import ./project.nix { inherit (inputs) hls-src hs-bindgen-src libclang-src; });
haskell = project.haskell-nix.project;
pkgs = project.nixpkgs.extend (import inputs.rust-overlay);
rust = (inputs.crane.mkLib pkgs).overrideToolchain (p: p.rust-bin.selectLatestNightlyWith (
pkgs = (import inputs.nixpkgs { inherit system; }).extend (import inputs.rust-overlay);
nix-haskell = import inputs.nix-haskell { inherit system inputs; };
crane = (inputs.crane.mkLib pkgs).overrideToolchain (p: p.rust-bin.selectLatestNightlyWith (
toolchain: toolchain.default.override {
extensions = [ "rust-src" ];
targets = [ "x86_64-unknown-linux-gnu" ];
}
));
project =
(nix-haskell (import ./project.nix { inherit (inputs) hls-src hs-bindgen-src libclang-src; inherit garnet-rs; })
).project.haskell-nix;
garnet-rs = crane.buildPackage {
src = crane.cleanCargoSource ./rust;
doCheck = false;
installPhaseCommand = ''
mkdir -p $out/lib $out/include
cp target/release/libgarnet_rs.a $out/lib/libCgarnet_rs.a
cp target/release/garnet_rs.h $out/include/
'';
};
in
{
rec {
defaultPackage = packages.garnet-exe;
packages = let garnet = project.hsPkgs.garnet; in {
inherit garnet-rs;
garnet-exe = garnet.components.exes.garnet;
garnet-lib = garnet.components.library;
};
devShells.default = pkgs.mkShell {
inputsFrom = [
(haskell.shell.overrideAttrs (old: {
shellHook = builtins.replaceStrings [ "*wasm*|)" ] [ "*wasm*)" ] old.shellHook;
}))
(rust.devShell { })
project.shell
(crane.devShell { })
];
packages = with pkgs; [
bacon

View File

@ -28,11 +28,13 @@ common common
-Wall
-fdefer-type-errors
build-depends:
base,
bytestring,
extra,
mtl,
process,
text,
vector,
library
import: common
@ -41,9 +43,8 @@ library
GarnetRs.Wrapped
hs-source-dirs: lib
include-dirs: rust/target/debug
extra-bundled-libraries: garnet_rs
extra-bundled-libraries: Cgarnet_rs
build-depends:
base,
hs-bindgen,
hs-bindgen-runtime,
primitive,
@ -58,5 +59,4 @@ executable garnet
-rtsopts
-with-rtsopts=-N
build-depends:
base,
garnet,

View File

@ -42,7 +42,7 @@ do
withHsBindgen
def
{ clang = def{extraIncludeDirs = Pkg "rust/target/debug" : systemDirs}
, fieldNamingStrategy = EnableRecordDot
, fieldNamingStrategy = OmitFieldPrefixes
}
def
$ hashInclude "garnet_rs.h"

View File

@ -9,12 +9,15 @@ module GarnetRs.Wrapped (
helloShape,
add,
sumTree,
sumSlice,
printOptional,
) where
import Control.Monad.Cont
import Control.Monad.Trans
import Data.ByteString
import Data.Function
import Data.Vector.Storable qualified as V
import Data.Word
import Foreign
import Foreign.C
@ -34,8 +37,9 @@ data Shape
| Rectangle CDouble CDouble
convertShape :: Shape -> Raw.Shape
convertShape = \case
Circle r -> Raw.Shape Raw.Circle $ Raw.set_shape_body_circle $ Raw.Circle_Body r
Rectangle w h -> Raw.Shape Raw.Rectangle $ Raw.set_shape_body_rectangle $ Raw.Rectangle_Body w h
Circle r -> Raw.Shape Raw.Circle $ Raw.set_shape_circle_circle $ Raw.Circle_Body r
-- hmm, unintuitive name
Rectangle w h -> Raw.Shape Raw.Rectangle $ Raw.set_shape_circle_rectangle $ Raw.Rectangle_Body w h
data BTree a
= Leaf a
@ -43,27 +47,35 @@ data BTree a
withBTree :: BTree Int64 -> (Raw.BTreeC -> IO a) -> IO a
withBTree =
runContT . fix \f -> \case
Leaf v -> pure $ Raw.BTreeC Raw.Leaf $ Raw.set_bTreeC_body_leaf $ Raw.Leaf_Body v
Leaf v -> pure $ Raw.BTreeC Raw.Leaf $ Raw.set_bTreeC_leaf_leaf $ Raw.Leaf_Body v
Fork l r -> do
lRaw <- f l
rRaw <- f r
lPtr <- ContT alloca
rPtr <- ContT alloca
lift $ poke lPtr lRaw >> poke rPtr rRaw
pure . Raw.BTreeC Raw.Fork . Raw.set_bTreeC_body_fork $
pure . Raw.BTreeC Raw.Fork . Raw.set_bTreeC_leaf_fork $
Raw.Fork_Body (unsafeFromPtr lPtr) (unsafeFromPtr rPtr)
hello :: ByteString -> IO ()
hello s = useAsCString s $ Raw.hello . unsafeFromPtr
hello = flip useAsCString $ Raw.hello . unsafeFromPtr
helloStruct :: T -> IO ()
helloStruct = Raw.hello_struct . convertT
helloStruct = flip with (Raw.hello_struct . unsafeFromPtr) . convertT
helloShape :: Shape -> IO ()
helloShape = Raw.hello_shape . convertShape
helloShape = flip with (Raw.hello_shape . unsafeFromPtr) . convertShape
add :: Int64 -> Int64 -> Int64
add = Raw.add
sumTree :: BTree Int64 -> Int64
sumTree = unsafePerformIO . flip withBTree Raw.sum_tree
sumTree = unsafePerformIO . flip withBTree (flip with $ Raw.sum_tree . unsafeFromPtr)
sumSlice :: V.Vector Int64 -> Int64
sumSlice v = unsafePerformIO $ V.unsafeWith v \p -> Raw.sum_slice (unsafeFromPtr p) (fromIntegral $ V.length v)
printOptional :: Maybe Int8 -> IO ()
printOptional = \case
Nothing -> Raw.print_optional (unsafeFromPtr nullPtr)
Just t -> with t (Raw.print_optional . unsafeFromPtr)

View File

@ -1,6 +1,7 @@
{ hls-src
, hs-bindgen-src
, libclang-src
, garnet-rs
}:
{
name = "garnet";
@ -23,6 +24,19 @@
libs = [ pkgs.llvmPackages.libclang ];
};
})
(_: {
packages.garnet.components.library = {
preConfigure = ''
mkdir -p rust/target/debug
ln -s ${garnet-rs}/include/garnet_rs.h rust/target/debug/garnet_rs.h
ln -s ${garnet-rs}/lib/libCgarnet_rs.a rust/target/debug/libCgarnet_rs.a
'';
preInstall = ''
cp ${garnet-rs}/lib/libCgarnet_rs.a dist/build/libCgarnet_rs.a
'';
configureFlags = [ "--extra-lib-dirs=${garnet-rs}/lib" ];
};
})
];
shell = {
tools = {

View File

@ -1,43 +1,19 @@
use std::env;
use std::fs;
use std::path::PathBuf;
fn main() {
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let profile = env::var("PROFILE").unwrap();
let bindings = cbindgen::Builder::new()
cbindgen::Builder::new()
.with_crate(&crate_dir)
.with_language(cbindgen::Language::C)
.with_style(cbindgen::Style::Tag)
.generate()
.expect("Unable to generate bindings");
// TODO vibe-coded workaround for hs-bindgen issue:
// https://github.com/well-typed/hs-bindgen/issues/1649#issuecomment-3994425922
let mut buf = Vec::new();
bindings.write(&mut buf);
let header = String::from_utf8(buf).unwrap();
let mut patched = String::new();
let mut saw_union = false;
for line in header.lines() {
if line == " };" && saw_union {
patched.push_str(" } body;\n");
saw_union = false;
continue;
}
if line == " union {" {
saw_union = true;
}
patched.push_str(line);
patched.push('\n');
}
fs::write(
.expect("Unable to generate bindings")
.write_to_file(
PathBuf::from(&crate_dir)
.join("target")
.join(&profile)
.join("garnet_rs.h"),
patched,
)
.unwrap();
);
}

View File

@ -3,6 +3,7 @@
use std::{
ffi::{CStr, c_char},
ops::Add,
slice,
};
fn say_hello(name: &str) {
@ -22,7 +23,7 @@ struct T {
}
#[unsafe(no_mangle)]
extern "C" fn hello_struct(t: T) -> () {
extern "C" fn hello_struct(t: &T) -> () {
say_hello(&format!("{:?}", t))
}
@ -34,7 +35,7 @@ enum Shape {
}
#[unsafe(no_mangle)]
extern "C" fn hello_shape(s: Shape) -> () {
extern "C" fn hello_shape(s: &Shape) -> () {
say_hello(&format!("{:?}", s))
}
@ -78,6 +79,19 @@ enum BTreeC {
}
#[unsafe(no_mangle)]
extern "C" fn sum_tree(t: BTreeC) -> i64 {
(unsafe { std::mem::transmute::<_, &BTree<i64>>(&t) }).sum()
extern "C" fn sum_tree(t: &BTreeC) -> i64 {
(unsafe { std::mem::transmute::<_, &BTree<i64>>(t) }).sum()
}
#[unsafe(no_mangle)]
extern "C" fn sum_slice(v: *const i64, s: usize) -> i64 {
unsafe { slice::from_raw_parts(v, s) }.iter().sum()
}
#[unsafe(no_mangle)]
extern "C" fn print_optional(x: Option<&i8>) -> () {
match x {
Some(x) => println!("{}", x / 2),
None => {}
}
}