The library we will be building today is called Pythagoras. It is a simple library for calculating the length of a triangle using the Pythagorean Theorem.
The repository for Pathagoras can be found on Github
- A basic understanding of haskell type classes.
- Basic understanding of the terminal and GHCi
- Eager to learn
- Simple functions to calculate the length of triangles using the Pythagorean Theorem.
- Simple names for functions to minimize confusion.
- Learn
- Create Directory called Pythagoras
cd
Inside your Pythagoras directory and issue the commandcabal init
- At this point you will be prompted to configure your .cabal package. These are the details you find on the homepage of a hackage library under Properties. It looks like this, well ours will:
-- Initial Pythagoras.cabal generated by cabal init. For further -- documentation, see http://haskell.org/cabal/users-guide/
name: Pythagoras
version: 0.1.0.0
synopsis: A simple library for doing the Pythagorean Theorem.
homepage: http://github.com/Cortlandd/Pythagoras
license: PublicDomain
license-file: LICENSE
author: Cortland Walker
maintainer: cortlandits@gmail.com
category: Math
build-type: Simple
cabal-version: >=1.10
library
-- Other library packages from which modules are imported.
build-depends: base >=4.8 && <4.9
-- Directories containing source files.
hs-source-dirs: src
-- Base language which the package is written in.
default-language: Haskell2010
```
3.1. In some cases your src would look something like this for a library:
src/
Pythagoras.hs
Pythagoras
With this, the Pythagoras/
folder is where your source code goes, and Pythagoras.hs
is the module file which imports all the source code from Pythagoras/
. But in our case, we will only need 1 file inside of our src
.
-
Now you're going to create your source code file inside
src
. Name itPythagoras.hs
. When you first go into GHCi, you see something calledPrelude>
. Well, Prelude is simply a module being loaded by default With it, comes it's functions (map, head, sum, etc). With that file created, start by setting up the module name:-- Pythagoras.hs module Pythagoras where
-
Next, were going to write our functions. They will takes 2 arguments and are in sequential order of the abc's. We will do this for each function.
-- Pythagoras.hs module Pythagoras where solveForA :: (Floating a, Ord a) => a -> a -> a solveForA b c | b > c = error "The hypotenuse c is always larger than the legs a and b." | otherwise = sqrt (c^2 - b^2) solveForB :: (Floating a, Ord a) => a -> a -> a solveForB a c | a > c = error "The hypotenuse c is always larger than the legs a and b." | otherwise = sqrt (c^2 - a^2) solveForC :: (Floating a) => a -> a -> a solveForC a b = sqrt (a^2 + b^2)
-
Lets test the functions inside Pythagoras.hs. Save this file, and inside the Pythagoras.hs directory, run GHCi:
#> GHCi Prelude> :l Pythagoras.hs [1 of 1] Compiling Pythagoras ( Pythagoras.hs, interrupted ) Ok, modules loaded: Pythagoras. *Pythagoras> :browse solveForA :: (Floating a, Ord a) => a -> a -> a solveForB :: (Floating a, Ord a) => a -> a -> a solveForC :: (Floating a) => a -> a -> a *Pythagoras> solveForA 9 15 12.0 *Pythagoras> solveForB 4 8 6.928203230275509 *Pythagoras> solveForC 5 12 13.0
You now have access to all of your previously created functions from
Pythagoras.hs
-
Now, lets use the functions in our library from another source file. Inside the same directory as Pythagoras.hs, create a file called TestPythagoras.hs.
-- TestPythagoras.hs module TestPythagoras where import Pythagoras main :: IO () main = print (solveForA 7 25)
Now if you load
TestPythagoras.hs
inside GHCi#> GHCi Prelude> :l TestPythagoras.hs [1 of 2] Compiling Pythagoras ( Pythagoras.hs, interpreted ) [2 of 2] Compiling TestPythagoras ( TestPythagoras.hs, interpreted ) Ok, modules loaded: Pythagoras, TestPythagoras *TestPythagoras> main 24.0
-
Now you officially have a working Haskell Library. Uploading to Hackage is probably beyond the scope of this tutorial so I won't. But for now, make additions to Pythagoras, perfect it. Go out and explore the world of Haskell.
- Know your arsenal. Be aware of the tools at your disposal in haskell (head, tail, map, foldr, etc). Ignorance of this can confuse you. You get coders block. Don't reinvent the wheel when you don't have to.
- A little trick I do that helps me write functions. Write out your intended functions use case.
-- I have my type signature all :: (a -> Bool) -> [a] -> Bool -- This is how I want all to behave all even [2, 4, 6, 8, 10] => True {- "even" is already a function in Haskell. Again, back to tip 1. Know your arsenal. Don't reinvent the wheel if it isnt necessary. -}
The initial Pythagoras.hs was meant to be beginner friendly, and easy to understand. A way to build it which...WHY IS THIS DONE. PROFESSIONAL INPUT WOULD BE HELPFUL
-- All functions will be contained in a module called: Pythagoras
module Pythagoras where {- a² + b² = c² -}
solveForA :: (Floating a, Ord a) => a -> a -> Maybe a
solveForA b c
| b > c = Nothing
| otherwise = Just (sqrt (c^2 - b^2))
solveForB :: (Floating a, Ord a) => a -> a -> Maybe a
solveForB a c
| a > c = Nothing
| otherwise = Just (sqrt (c^2 - a^2))
solveForC :: (Floating a) => a -> a -> Maybe a
solveForC a b = Just (sqrt (a^2 + b^2))
-- Hmm, where to begin. How do I approach this?