├── .gitignore ├── .travis.yml ├── ChangeLog.md ├── LICENSE ├── README.md ├── Setup.hs ├── data └── binary.txt ├── default.nix ├── nnaskell.cabal ├── src ├── Binary.hs ├── MNIST.hs ├── Nnaskell.hs └── Xor.hs └── stack.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/emacs,haskell 3 | 4 | ### Emacs ### 5 | # -*- mode: gitignore; -*- 6 | *~ 7 | \#*\# 8 | /.emacs.desktop 9 | /.emacs.desktop.lock 10 | *.elc 11 | auto-save-list 12 | tramp 13 | .\#* 14 | 15 | # Org-mode 16 | .org-id-locations 17 | *_archive 18 | 19 | # flymake-mode 20 | *_flymake.* 21 | 22 | # eshell files 23 | /eshell/history 24 | /eshell/lastdir 25 | 26 | # elpa packages 27 | /elpa/ 28 | 29 | # reftex files 30 | *.rel 31 | 32 | # AUCTeX auto folder 33 | /auto/ 34 | 35 | # cask packages 36 | .cask/ 37 | dist/ 38 | 39 | # Flycheck 40 | flycheck_*.el 41 | 42 | # server auth directory 43 | /server/ 44 | 45 | # projectiles files 46 | .projectile 47 | projectile-bookmarks.eld 48 | 49 | # directory configuration 50 | .dir-locals.el 51 | 52 | # saveplace 53 | places 54 | 55 | # url cache 56 | url/cache/ 57 | 58 | # cedet 59 | ede-projects.el 60 | 61 | # smex 62 | smex-items 63 | 64 | # company-statistics 65 | company-statistics-cache.el 66 | 67 | # anaconda-mode 68 | anaconda-mode/ 69 | 70 | ### Haskell ### 71 | dist 72 | dist-* 73 | cabal-dev 74 | *.o 75 | *.hi 76 | *.chi 77 | *.chs.h 78 | *.dyn_o 79 | *.dyn_hi 80 | .hpc 81 | .hsenv 82 | .cabal-sandbox/ 83 | cabal.sandbox.config 84 | *.prof 85 | *.aux 86 | *.hp 87 | *.eventlog 88 | .stack-work/ 89 | cabal.project.local 90 | .HTF/ 91 | 92 | # End of https://www.gitignore.io/api/emacs,haskell 93 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # This is the simple Travis configuration, which is intended for use 2 | # on applications which do not require cross-platform and 3 | # multiple-GHC-version support. For more information and other 4 | # options, see: 5 | # 6 | # https://docs.haskellstack.org/en/stable/travis_ci/ 7 | # 8 | # Copy these contents into the root directory of your Github project in a file 9 | # named .travis.yml 10 | 11 | # Use new container infrastructure to enable caching 12 | sudo: false 13 | 14 | # Do not choose a language; we provide our own build tools. 15 | language: generic 16 | 17 | # Caching so the next build will be fast too. 18 | cache: 19 | directories: 20 | - $HOME/.stack 21 | 22 | # Ensure necessary system libraries are present 23 | addons: 24 | apt: 25 | packages: 26 | - libgmp-dev 27 | - libopenblas-dev 28 | 29 | before_install: 30 | # Download and unpack the stack executable 31 | - mkdir -p ~/.local/bin 32 | - export PATH=$HOME/.local/bin:$PATH 33 | - travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack' 34 | 35 | install: 36 | # Build dependencies 37 | - stack --no-terminal --install-ghc test --only-dependencies 38 | 39 | script: 40 | # Build the package, its tests, and its docs and run the tests 41 | - stack --no-terminal test --haddock --no-haddock-deps 42 | -------------------------------------------------------------------------------- /ChangeLog.md: -------------------------------------------------------------------------------- 1 | # Revision history for nnaskell 2 | 3 | ## 0.1.0.0 -- YYYY-mm-dd 4 | 5 | * First version. Released on an unsuspecting world. 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 rexim 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included 12 | in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Tsoding](https://img.shields.io/badge/twitch.tv-tsoding-purple?logo=twitch&style=for-the-badge)](https://www.twitch.tv/tsoding) 2 | [![Build Status](https://travis-ci.org/tsoding/nnaskell.svg?branch=master)](https://travis-ci.org/tsoding/nnaskell) 3 | 4 | # Nnaskell 5 | 6 | Neural Network in Haskell 7 | 8 | ## Quick Start 9 | 10 | ```console 11 | $ nix-shell # only for NixOS 12 | $ stack build 13 | $ stack ghci 14 | > nn <- randomNN [2, 2, 1] 15 | > xorTD 16 | [([0.0,0.0],[0.0]), 17 | ([1.0,0.0],[1.0]), 18 | ([0.0,1.0],[1.0]), 19 | ([1.0,1.0],[0.0])] 20 | > let trainedNN = head $ drop 1000 $ optimizeCost (cost xorTD) nn 21 | > activateNN trainedNN $ vector [0.0, 0.0] 22 | [4.045689665702377e-3] 23 | > activateNN trainedNN $ vector [1.0, 0.0] 24 | [0.9970477904605844] 25 | > 26 | ``` 27 | 28 | ## Support 29 | 30 | You can support my work via 31 | 32 | - Twitch channel: https://www.twitch.tv/subs/tsoding 33 | - Patreon: https://www.patreon.com/tsoding 34 | -------------------------------------------------------------------------------- /Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /data/binary.txt: -------------------------------------------------------------------------------- 1 | NN {nnWs = [(8><4) 2 | [ -0.247779799270907, -0.9052121663681219, -0.3371819663295399, -8.351916597838294e-2 3 | , 0.39928530049453914, 0.8921098662121518, 0.28162690734639795, 0.9523842538463059 4 | , 0.8765164281727031, -0.26347153734918716, -0.9803029558413714, 0.23947083661857516 5 | , 0.15285077020314608, 0.4235443004639323, 0.24981087549232583, -0.3428667908297529 6 | , -0.26433120583813996, 0.9651530278874714, 0.11496606991097025, 0.3193044825655238 7 | , 0.4304623740712781, 0.1342368596134027, 0.6704751863414371, 0.8625650445756443 8 | , 0.44286167930436027, 0.379471037658335, -0.903977351965995, 0.38881570426660383 9 | , 0.8022803854150209, 0.9498542861327428, 0.40345702446463805, 0.5836310841823364 ],(16><8) 10 | [ -0.4665962157573096, -0.7269953912738489, 0.68157929686036, -8.200764016711837e-2, 0.5420946173850811, 0.8592731637834159, 0.2735717733333223, 0.3178709325610072 11 | , -0.3139028245009885, 0.15428591629134591, 0.20555834247118265, -0.7598431154619181, -0.7729633507740585, 0.6246948077493377, 0.28069000572177405, 0.45181959333748734 12 | , -0.8784177961161701, 0.3739639051098862, -3.6988914493081504e-2, 0.9884595277125867, 0.10162452411982326, 0.9384563293911063, 0.22388087979631632, -0.6207490308469303 13 | , 0.44575568273233523, 0.2688272650743033, 0.941713752135291, 0.7539604782052771, -0.8793405874836333, -0.5034224308616291, -0.4714844152501032, 0.28545718182335755 14 | , 0.5584959362641224, 0.5023898245408924, -9.896336341928613e-2, 0.7317338963812012, -0.32130777748871964, 0.8244823103966614, 0.17346531496833872, 0.4873164570847579 15 | , -0.5498602025443422, 0.7057742942761547, -0.8882304403070325, 0.9108011257591231, 0.6087854991117898, -0.5585028712967453, -3.5839912242399796e-2, -0.22234339108923096 16 | , 0.302704565546674, 0.8345871300790466, -0.15875589580236316, -0.14173219538253412, 0.9925878901082832, 0.206662487235465, 2.3271413082680992e-2, 0.4005515948571037 17 | , 0.4977480636954885, 0.18035738180948457, -0.3985415737191469, 0.391572058830048, 0.9970473538867906, 0.4263088236738066, -0.3947937122788219, -8.996664346183092e-2 18 | , 0.5124288467465987, -0.38366940681844297, 0.8737585900749261, -0.5583052294866335, 0.8491986428232596, 0.2560012664731288, 0.15239220309039125, 0.9082647174245839 19 | , -5.137487869831037e-2, 0.12209736923055114, -0.8532104733369641, 0.18233400468713534, 0.8048170068501217, 0.5769766802593614, 0.45097057478121716, 1.1406053674016814e-2 20 | , 0.3506919231835237, -0.26319163719752536, 0.8239587165175026, -0.9537534364994984, 0.9874788901413196, -0.95660730133111, 0.761829510068857, -0.28859398023282945 21 | , 0.39987451103189886, -0.9857092008555841, -6.046837842041519e-3, 0.46418844577548235, 0.9199660969055745, 0.13436334721235688, -0.6305497668479554, -4.9884776004382125e-2 22 | , 0.9442598050205189, -0.5064803857905611, 0.6044829625809018, 0.5522740989663362, 0.16080879054570985, -0.42584557029919456, 0.7565422285136298, 0.9916728993274162 23 | , 0.24384662476379293, -0.6012881200298685, 0.9581321242691159, 0.4056632862169416, -0.162622876510357, 0.4061276104874161, 0.8118913301438944, -0.17058009249761819 24 | , 0.5032289335025586, 0.5383812757718924, -0.6304854591811837, 0.5076222036889746, 0.8963422902117248, 0.5270673008517315, -0.6421699525455509, -0.3698524337468303 25 | , 0.6343442955999508, 0.9934555795064426, 4.479308845217567e-2, -0.34414816998703124, -0.5348155787155169, 0.8404609825097822, -0.6905763138106986, -0.5692251970228954 ]], nnBs = [[-0.3783313614784114,-0.5002044064000779,0.7969729071397744,-0.4748608284096876,0.21822824306147415,-0.36619305777686173,-0.48411821343402095,-0.7374397624142335],[0.34988161568780485,-8.149451351490655e-2,-0.2819972132030577,-0.34916054315025247,-0.42113590812434754,-0.6058294321616173,0.6612876148169002,-0.7713925430511368,0.30880146618003534,-0.8918094655157969,-0.17273292113558258,0.5184867389302121,-0.2181444308730187,-0.6889488634410004,-0.8503322722187976,-0.949842668757451]]} -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | let 2 | nixos = import {}; 3 | fixedOpenblas = nixos.openblas.override { blas64 = false; }; 4 | in rec { 5 | nnaskellEnv = nixos.stdenv.mkDerivation { 6 | name = "nnaskell-env"; 7 | buildInputs = [ nixos.ghc nixos.cabal-install nixos.stack fixedOpenblas ]; 8 | LD_LIBRARY_PATH="${fixedOpenblas}/lib"; 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /nnaskell.cabal: -------------------------------------------------------------------------------- 1 | -- Initial nnaskell.cabal generated by cabal init. For further 2 | -- documentation, see http://haskell.org/cabal/users-guide/ 3 | 4 | -- The name of the package. 5 | name: nnaskell 6 | 7 | -- The package version. See the Haskell package versioning policy (PVP) 8 | -- for standards guiding when and how versions should be incremented. 9 | -- https://wiki.haskell.org/Package_versioning_policy 10 | -- PVP summary: +-+------- breaking API changes 11 | -- | | +----- non-breaking API additions 12 | -- | | | +--- code changes with no API change 13 | version: 0.1.0.0 14 | 15 | -- A short (one-line) description of the package. 16 | synopsis: Neural Network in Haskell 17 | 18 | -- A longer description of the package. 19 | -- description: 20 | 21 | -- URL for the project homepage or repository. 22 | homepage: https://github.com/tsoding/nnaskell 23 | 24 | -- The license under which the package is released. 25 | license: MIT 26 | 27 | -- The file containing the license text. 28 | license-file: LICENSE 29 | 30 | -- The package author(s). 31 | author: rexim 32 | 33 | -- An email address to which users can send suggestions, bug reports, and 34 | -- patches. 35 | maintainer: reximkut@gmail.com 36 | 37 | -- A copyright notice. 38 | -- copyright: 39 | 40 | category: Math 41 | 42 | build-type: Simple 43 | 44 | -- Extra files to be distributed with the package, such as examples or a 45 | -- README. 46 | extra-source-files: ChangeLog.md 47 | 48 | -- Constraint on the version of Cabal needed to build this package. 49 | cabal-version: >=1.10 50 | 51 | 52 | library 53 | -- Modules exported by the library. 54 | exposed-modules: Nnaskell 55 | , Xor 56 | 57 | -- Modules included in this library but not exported. 58 | -- other-modules: 59 | 60 | -- LANGUAGE extensions used by modules in this package. 61 | -- other-extensions: 62 | 63 | -- Other library packages from which modules are imported. 64 | build-depends: base >=4.9 && <4.10 65 | , vector 66 | , random 67 | , hmatrix 68 | , bytestring 69 | 70 | -- Directories containing source files. 71 | hs-source-dirs: src 72 | 73 | -- Base language which the package is written in. 74 | default-language: Haskell2010 75 | 76 | 77 | -------------------------------------------------------------------------------- /src/Binary.hs: -------------------------------------------------------------------------------- 1 | module Binary where 2 | 3 | import Nnaskell 4 | import Numeric.LinearAlgebra.Data 5 | 6 | binaryNN :: IO NN 7 | binaryNN = loadNN "./data/binary.txt" 8 | 9 | binaryTD :: [(Vector R, Vector R)] 10 | binaryTD = zip (map binaryInput ns) (map binaryOutput ns) 11 | where ns = [0 .. 15] 12 | 13 | binaryInput :: Int -> Vector R 14 | binaryInput x = vector $ map fromIntegral [ x `mod` 2 15 | , (x `div` 2) `mod` 2 16 | , (x `div` 4) `mod` 2 17 | , (x `div` 8) `mod` 2] 18 | 19 | binaryOutput :: Int -> Vector R 20 | binaryOutput x = accum (vector $ replicate 16 0.0) (\a _ -> a) [(x, 1.0)] 21 | -------------------------------------------------------------------------------- /src/MNIST.hs: -------------------------------------------------------------------------------- 1 | module MNIST ( readLabelsFile 2 | , readImagesFile 3 | ) where 4 | 5 | import Text.Printf 6 | import Data.Word 7 | import qualified Data.ByteString.Lazy as BL 8 | 9 | data Image = Image { imageSize :: (Int, Int) 10 | , imageData :: [Word8] 11 | } deriving (Show) 12 | 13 | bytesAsInt :: BL.ByteString -> Int 14 | bytesAsInt = foldl (\a x -> a * 0x100 + x) 0 . map fromIntegral . BL.unpack 15 | 16 | magicNumberParser :: Int -> BL.ByteString -> IO BL.ByteString 17 | magicNumberParser expectedNumber bs 18 | | expectedNumber == actualNumber = return rest 19 | | otherwise = ioError 20 | $ userError 21 | $ printf "Unexpected magic number: %d. Expected %d." actualNumber expectedNumber 22 | where actualNumber = bytesAsInt $ BL.take 4 bs 23 | rest = BL.drop 4 bs 24 | 25 | labelsParser :: BL.ByteString -> IO [Word8] 26 | labelsParser bs = 27 | let expectedCount = bytesAsInt $ BL.take 4 bs 28 | body = BL.drop 4 bs 29 | labels = BL.unpack body 30 | actualCount = length labels 31 | in if expectedCount == actualCount 32 | then return labels 33 | else ioError 34 | $ userError 35 | $ printf "Unexpected amount of labels. Expected: %d, but got %d" expectedCount actualCount 36 | 37 | imagesParser :: BL.ByteString -> IO [Image] 38 | imagesParser bs = 39 | let expectedCount = bytesAsInt $ BL.take 4 bs 40 | rows = bytesAsInt $ BL.take 4 $ BL.drop 4 bs 41 | cols = bytesAsInt $ BL.take 4 $ BL.drop 8 bs 42 | body = BL.drop 12 bs 43 | actualCount = fromIntegral $ BL.length body 44 | in if expectedCount * rows * cols == actualCount 45 | then return 46 | $ map (\bs -> Image { imageSize = (rows, cols) 47 | , imageData = bs 48 | }) 49 | $ chunks (rows * cols) 50 | $ BL.unpack body 51 | else ioError 52 | $ userError 53 | $ printf "Unexpected amount of bytes. Expected: %d, but got %d" (expectedCount * rows * cols) actualCount 54 | 55 | readLabelsFile :: FilePath -> IO [Word8] 56 | readLabelsFile fileName = 57 | BL.readFile fileName 58 | >>= magicNumberParser 2049 59 | >>= labelsParser 60 | 61 | readImagesFile :: FilePath -> IO [Image] 62 | readImagesFile fileName = 63 | BL.readFile fileName 64 | >>= magicNumberParser 2051 65 | >>= imagesParser 66 | 67 | chunks :: Int -> [a] -> [[a]] 68 | chunks _ [] = [] 69 | chunks n xs = take n xs : chunks n (drop n xs) 70 | 71 | pixelToChar :: Word8 -> Char 72 | pixelToChar p = fst $ head $ dropWhile (\(_, i) -> p > i) pallete 73 | where pallete = [ ('░', (255 `div` n)) 74 | , ('▒', (255 `div` n) * 2) 75 | , ('▓', (255 `div` n) * 3) 76 | , ('█', 255) ] 77 | n = 4 78 | 79 | displayImage :: Image -> String 80 | displayImage image = unlines 81 | $ chunks (2 * cols) 82 | $ concatMap (replicate 2 . pixelToChar) 83 | $ imageData image 84 | where (_, cols) = imageSize image 85 | -------------------------------------------------------------------------------- /src/Nnaskell.hs: -------------------------------------------------------------------------------- 1 | module Nnaskell ( NN(..) 2 | , randomNN 3 | , activateNN 4 | , cost 5 | , optimizeCost 6 | , loadNN 7 | , saveNN 8 | ) where 9 | 10 | import Data.Function 11 | import Data.List 12 | import Control.Monad 13 | import System.Random 14 | import Numeric.LinearAlgebra.Data 15 | import Numeric.LinearAlgebra.HMatrix 16 | 17 | data NN = NN { nnWs :: [Matrix R] 18 | , nnBs :: [Vector R] 19 | } deriving (Show, Read) 20 | 21 | randomVec :: Int -> IO (Vector R) 22 | randomVec n = vector <$> (replicateM n $ randomRIO (-1.0, 1.0)) 23 | 24 | randomMatrix :: Int -> Int -> IO (Matrix R) 25 | randomMatrix n m = matrix m <$> (replicateM ((*) n m) $ randomRIO (-1.0, 1.0)) 26 | 27 | randomLayer :: Int -> Int -> IO (Matrix R, Vector R) 28 | randomLayer n m = liftM2 (\ws bs -> (ws, bs)) (randomMatrix m n) (randomVec m) 29 | 30 | randomNN :: [Int] -> IO NN 31 | randomNN ns = do (ws, bs) <- unzip <$> (sequence $ map (uncurry randomLayer) $ pairScan ns) 32 | return $ NN { nnWs = ws 33 | , nnBs = bs 34 | } 35 | 36 | sigmoid :: R -> R 37 | sigmoid t = 1 / (1 + exp (-1 * t)) 38 | 39 | sigmoidVec :: Vector R -> Vector R 40 | sigmoidVec = fromList . map sigmoid . toList 41 | 42 | activateLayer :: Vector R -> (Matrix R, Vector R) -> Vector R 43 | activateLayer as (ws, bs) = sigmoidVec (ws #> as + bs) 44 | 45 | activateNN :: NN -> Vector R -> Vector R 46 | activateNN nn as = foldl activateLayer as $ zip ws bs 47 | where ws = nnWs nn 48 | bs = nnBs nn 49 | 50 | pairScan :: [a] -> [(a, a)] 51 | pairScan (x:y:rest) = (x, y) : pairScan (y:rest) 52 | pairScan _ = [] 53 | 54 | cost :: [(Vector R, Vector R)] -> NN -> R 55 | cost td nn = (sum $ map inputCost td) / n 56 | where inputCost (input, output) = sumElements $ cmap (** 2) (activateNN nn input - output) 57 | n = fromIntegral $ length td 58 | 59 | stepBias :: NN -> Int -> R -> NN 60 | stepBias nn updateIdx s = nn { nnBs = map (\(v, idx) -> if idx <= updateIdx && updateIdx < idx + size v 61 | then accum v (+) [(updateIdx - idx, s)] 62 | else v) 63 | $ zip bs 64 | $ scanl (\idx v -> idx + size v) 0 bs 65 | } 66 | where bs = nnBs nn 67 | 68 | stepWeight :: NN -> Int -> R -> NN 69 | stepWeight nn updateIdx s = nn { nnWs = map (\(mx, idx) -> let (n, m) = size mx 70 | effIdx = updateIdx - idx 71 | in if idx <= updateIdx && updateIdx < idx + (n * m) 72 | then accum mx (+) [((effIdx `div` m, effIdx `mod` m), s)] 73 | else mx) 74 | $ zip ws 75 | $ scanl (\idx m -> idx + uncurry (*) (size m)) 0 ws 76 | } 77 | where ws = nnWs nn 78 | 79 | class Domain d where 80 | countArgs :: d -> Int 81 | stepArg :: d -> Int -> R -> d 82 | 83 | instance Domain NN where 84 | countArgs nn = bsCount + wsCount 85 | where bsCount = sum $ map (length . toList) $ nnBs nn 86 | wsCount = sum $ map length $ concatMap toLists $ nnWs nn 87 | stepArg nn idx s = if idx < bsCount 88 | then stepBias nn idx s 89 | else stepWeight nn (idx - bsCount) s 90 | where bsCount = sum $ map (length . toList) $ nnBs nn 91 | 92 | optimizeCost :: Domain d => (d -> R) -> d -> [d] 93 | optimizeCost cost d = scanl optimizeStep d $ cycle [0 .. n - 1] 94 | where n = countArgs d 95 | optimizeStep d idx = minimumBy (compare `on` cost) $ map (stepArg d idx) [-step, 0, step] 96 | step = 0.1 97 | 98 | loadNN :: FilePath -> IO NN 99 | loadNN filePath = read <$> readFile filePath 100 | 101 | saveNN :: FilePath -> NN -> IO () 102 | saveNN filePath nn = writeFile filePath $ show nn 103 | -------------------------------------------------------------------------------- /src/Xor.hs: -------------------------------------------------------------------------------- 1 | module Xor where 2 | 3 | import Nnaskell 4 | import Numeric.LinearAlgebra.Data 5 | 6 | xorNN = do nn <- randomNN [2, 2, 1] 7 | return $ head $ drop 5000 $ optimizeCost (cost xorTD) nn 8 | 9 | xorTD :: [(Vector R, Vector R)] 10 | xorTD = [ (vector [0.0, 0.0], vector [0.0]) 11 | , (vector [1.0, 0.0], vector [1.0]) 12 | , (vector [0.0, 1.0], vector [1.0]) 13 | , (vector [1.0, 1.0], vector [0.0]) 14 | ] 15 | -------------------------------------------------------------------------------- /stack.yaml: -------------------------------------------------------------------------------- 1 | # This file was automatically generated by 'stack init' 2 | # 3 | # Some commonly used options have been documented as comments in this file. 4 | # For advanced use and comprehensive documentation of the format, please see: 5 | # https://docs.haskellstack.org/en/stable/yaml_configuration/ 6 | 7 | # Resolver to choose a 'specific' stackage snapshot or a compiler version. 8 | # A snapshot resolver dictates the compiler version and the set of packages 9 | # to be used for project dependencies. For example: 10 | # 11 | # resolver: lts-3.5 12 | # resolver: nightly-2015-09-21 13 | # resolver: ghc-7.10.2 14 | # resolver: ghcjs-0.1.0_ghc-7.10.2 15 | # resolver: 16 | # name: custom-snapshot 17 | # location: "./custom-snapshot.yaml" 18 | resolver: lts-9.11 19 | 20 | # User packages to be built. 21 | # Various formats can be used as shown in the example below. 22 | # 23 | # packages: 24 | # - some-directory 25 | # - https://example.com/foo/bar/baz-0.0.2.tar.gz 26 | # - location: 27 | # git: https://github.com/commercialhaskell/stack.git 28 | # commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a 29 | # - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a 30 | # extra-dep: true 31 | # subdirs: 32 | # - auto-update 33 | # - wai 34 | # 35 | # A package marked 'extra-dep: true' will only be built if demanded by a 36 | # non-dependency (i.e. a user package), and its test suites and benchmarks 37 | # will not be run. This is useful for tweaking upstream packages. 38 | packages: 39 | - . 40 | # Dependency packages to be pulled from upstream that are not in the resolver 41 | # (e.g., acme-missiles-0.3) 42 | extra-deps: 43 | - hmatrix-0.18.1.0 44 | 45 | # Override default flag values for local packages and extra-deps 46 | flags: 47 | hmatrix: 48 | openblas: true 49 | 50 | # Extra package databases containing global packages 51 | extra-package-dbs: [] 52 | 53 | # Control whether we use the GHC we find on the path 54 | # system-ghc: true 55 | # 56 | # Require a specific version of stack, using version ranges 57 | # require-stack-version: -any # Default 58 | # require-stack-version: ">=1.5" 59 | # 60 | # Override the architecture used by stack, especially useful on Windows 61 | # arch: i386 62 | # arch: x86_64 63 | # 64 | # Extra directories used by stack for building 65 | # extra-include-dirs: [/path/to/dir] 66 | # extra-lib-dirs: [/path/to/dir] 67 | # 68 | # Allow a newer minor version of GHC than the snapshot specifies 69 | # compiler-check: newer-minor 70 | --------------------------------------------------------------------------------