2 years ago
#32930
nicolas
running a program in haskell with just nix installed
If I have nix
installed, I can run pretty much any program, without having it "installed".
- For instance a javascript program require
node
//in file helloworld.js
const http = require('http'); // Loads the http module
http.createServer((request, response) => {
response.writeHead(200, {
'Content-Type': 'text/plain'
});
response.write('Hello, World!\n');
response.end();
}).listen(1337);
and I can directly run it with
$(nix-build -E "with import <nixpkgs> { };nodejs")/bin/node helloworld.js
- For simple haskell, I can likewise both summon a haskell environment, and have it run directly with a bash script :
#! /usr/bin/env nix-shell
#! nix-shell -i runghc -p "haskellPackages.ghcWithPackages(p: with p; [type-level-sets])"
#! nix-shell -I nixpkgs=channel:nixos-21.11
-- courtesy jyrimatti https://gist.github.com/jyrimatti/bd139e91ed257d37bc57c08ac505fc3f
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeApplications #-}
module Main where
import Data.Type.Set (Set(..), Proxy(..))
class Get a s where
get :: Set s -> a
instance {-# OVERLAPS #-} Get a (a ': s) where
get (Ext a _) = a
instance {-# OVERLAPPABLE #-} Get a s => Get a (b ': s) where
get (Ext _ xs) = get xs
main :: IO ()
main = do
let lst = Ext "hello" $ Ext 10 $ Empty
putStrLn $ show $ get @String lst
However, say my program is more complicated, like the webserver example, and I want to target a particular package set. now all my dependencies are picked from that vetted set of packages which are known to be compatible with each others.
With stack
installed, this is easy :
#!/usr/bin/env stack
-- stack --resolver lts-18.21 script
-- this script makes use of the http-client library, which is in stackage
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.ByteString.Lazy.Char8 as L8
import Network.HTTP.Simple
-- An equivalent pure haskell file can also be run as
-- stack runghc --package http-conduit -- http.hs
main :: IO ()
main = do
response <- httpLBS "http://httpbin.org/get"
putStrLn $
"The status code was: "
++ show (getResponseStatusCode response)
print $ getResponseHeader "Content-Type" response
L8.putStrLn $ getResponseBody response
Is there an equivalent for nix
which would make it simple to (reliably !) launch some haskell program, along with its dependencies, without anything special installed apart from nix
?
I imagine something like :
#! /usr/bin/env nix-shell
#! nix-shell -i runghc -p "stackage.lts-18.21"
#! nix-shell -I nixpkgs=channel:nixos-21.11
-- this script makes use of the http-client library, which is in stackage
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.ByteString.Lazy.Char8 as L8
import Network.HTTP.Simple
-- An equivalent pure haskell file can also be run as
-- stack runghc --package http-conduit -- http.hs
main :: IO ()
main = do
response <- httpLBS "http://httpbin.org/get"
putStrLn $
"The status code was: "
++ show (getResponseStatusCode response)
print $ getResponseHeader "Content-Type" response
L8.putStrLn $ getResponseBody response
bash
haskell
nix
0 Answers
Your Answer