```module Chess.FEN ( fromFEN
, toFEN
, defaultFEN
, defaultBoard
) where

import Chess
import qualified Data.List as L
import           Data.Char
import           Data.Array
import           Data.Maybe

split [] delim = [""]
split (c:cs) delim
| c == delim = "" : rest
| otherwise = (c : head rest) : tail rest
where rest = split cs delim

unsplit [] delim = ""
unsplit (x:[]) delim = x
unsplit (x:xs) delim = x ++ delim ++ (unsplit xs delim)

fromFEN :: String -> Maybe Board
fromFEN fen = readPosition \$ words fen
Just \$ Board (clr turn) castle enpas board where
clr x = if x == "w" then White else Black
enpas = if enpassant == "-" then Nothing else Just \$ strToPos enpassant
board = listArray ((0,0),(7,7)) (concat \$ L.transpose \$ map makeLine (reverse boardLines))
boardLines = split pieces '/'
makeLine ls = foldr ((++) . pcs) [] ls
pcs a = if isDigit a then replicate (digitToInt a) Nothing else [Just (read [a])]

toFEN :: Board -> String
toFEN brd = pieces ++ " " ++ turnstr ++ " " ++ castString ++ " " ++ enpassantstr where
pieces = unsplit (map fenline \$ [ [ (board brd)!(j,7-i) | j<-[0..7]] | i<-[0..7]]) "/"
turnstr = if turn brd == White then "w" else "b"
enpassantstr = fromMaybe "-" (enpassant brd >>= \(x,y) -> return [chr (x+97), intToDigit (y+1)])
castString = if castlingAvail brd == "" then "-" else castlingAvail brd
fenline pcs = concatMap tos \$ foldr com [] pcs where
tos = either show show
com a b = case a of
Just x -> (Right x) : b
Nothing -> case b of
((Left n):xs) -> (Left (n+1)) : xs
_ -> (Left 1) : b

defaultFEN :: String
defaultFEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -"

defaultBoard :: Board
defaultBoard = fromJust \$ fromFEN defaultFEN
```