Showing posts with label haskell. Show all posts
Showing posts with label haskell. Show all posts

Wednesday, February 8, 2012

Scripting in Haskell and reading current playing song

If you use Xmonad as your prefered window manager you have to script some information for yourself. So I wanted to put my current playing song into the bottom bar.


On the image above you can see my bottom bar with the information of the current playing song. For this I use xmobar for putting this information into the bottom bar and mocp for getting the information which song is currently playing.

The nice thing is if you want to script with Haskell just put the following line to the first line of your script and you can run it after you give the appropriate permissions (chmod +x).
#!/usr/bin/env runhaskell
The following code will show you how to get a information from an external program and parse some important information and put it to stdout.
#!/usr/bin/env runhaskell

module Main where

import System.Process (readProcess)
import Data.List (isPrefixOf)

sizeOfString :: Int
sizeOfString = 47

split :: Eq a => a -> [a] -> [[a]]
split d = foldr f [[]]
  where f c l@(x:xs) | c == d = []:l
                     | otherwise = (c:x):xs

-- | my head function doesn't crash if there is an empty list                                                                                          
head' :: [String] -> String
head' [] = ""
head' (x:xs) = x

-- | my tail function doesn't chrash if there is an empty list                                                                                         
tail' :: [a] -> [a]
tail' [] = []
tail' (x:xs) = xs

line :: String -> IO [String]
line start = do
  s <- readProcess "mocp" ["-i"] []
  let t = split '\n' s
  let l = filter (isPrefixOf start) t
  return $ words $ head' l

reduceLine :: String -> String
reduceLine s
  | length s <= sizeOfString + 3 = s
  | otherwise = take sizeOfString s ++ "... "

main :: IO ()
main = do
  s <- line "SongTitle"
  a <- line "Artist"
  let song = foldr (++) "" $ map (++" ") $ tail' s
  let artist = foldr (++) "" $ map (++" ") $ tail' a
  if (length artist == 0)
    then if (length song == 0)
         then putStrLn $ "stop "
         else putStrLn $ reduceLine song
    else putStrLn $ reduceLine $ artist ++ ":: " ++ song
I know the code could be much shorter but its nice for learning Haskell and learn how to script with Haskell.

Tuesday, February 7, 2012

Open library files from /w ghci

If you want to get some information about a function in GHC just do
ghci> :t sum
sum :: Num a => [a] -> a -- Defined in Data.List
What do you do if you want to look at the source of that file just from /w the interpreter ghci? You could do following.

Download the source from ghci an put it wherever you want. For all Debianer out there just do following:
apt-get source ghc
After that you have to define a macro in ghci. You can also define this macro in the configuration file for ghci in $HOME/.ghc/ghci.conf.
:def source \s -> return $ ":! openGHCLib.sh " ++ s
Afterwards you have to write the script openGHCLib.sh and put it into your PATH. The script openGHCLib.sh look like:
#!/bin/bash

# path where you put the source files of ghc
base_path=$HOME/tmp/ghc-7.0.4/libraries/base
file=`echo $1 | tr '.' '/'`
hfile="${base_path}/${file}"

if [ -e "${hfile}.hs" ]; then
  ${EDITOR} "${hfile}.hs"
elif [ -e "${hfile}.lhs" ]; then
  ${EDITOR} "${hfile}.lhs"
else
  echo "file: ${hfile}.hs or ${hfile}.lhs does not exist"
  exit 1
fi
After that you can open the library file /w ghci.
ghci> :source Data.List