Skip to Content »
online discount medstore
advair diskus for sale
buy advair diskus without prescription
allegra for sale
buy allegra without prescription
aristocort for sale
buy aristocort without prescription
astelin for sale
buy astelin without prescription
atarax for sale
buy atarax without prescription
benadryl for sale
buy benadryl without prescription
buy clarinex without prescription
clarinex for sale
buy claritin without prescription
claritin for sale
buy flonase without prescription
flonase for sale
buy ventolin without prescription
ventolin for sale
amoxil for sale
buy amoxil without prescription
augmentin for sale
buy augmentin without prescription
bactrim for sale
buy bactrim without prescription
biaxin for sale
buy biaxin without prescription
buy cipro without prescription
cipro for sale
buy cleocin without prescription
cleocin for sale
buy dexone without prescription
dexone for sale
buy flagyl without prescription
flagyl for sale
buy levaquin without prescription
levaquin for sale
buy omnicef without prescription
omnicef for sale
amaryl for sale
buy amaryl without prescription
buy cozaar without prescription
cozaar for sale
buy diabecon without prescription
diabecon for sale
buy glucophage without prescription
glucophage for sale
buy glucotrol without prescription
glucotrol for sale
buy glucovance without prescription
glucovance for sale
buy micronase without prescription
micronase for sale
buy prandin without prescription
prandin for sale
buy precose without prescription
precose for sale
buy cialis professional without prescription
cialis professional for sale
buy cialis soft without prescription
cialis soft for sale
buy cialis super active without prescription
cialis super active for sale
buy cialis without prescription
cialis for sale
buy levitra without prescription
levitra for sale
buy viagra professional without prescription
viagra professional for sale
buy viagra soft without prescription
viagra soft for sale
buy viagra super active without prescription
viagra super active for sale
buy viagra super force without prescription
viagra super force for sale
buy viagra without prescription
viagra for sale
buy celebrex without prescription
celebrex for sale
buy colcrys without prescription
colcrys for sale
buy feldene without prescription
feldene for sale
buy imitrex without prescription
imitrex for sale
buy inderal without prescription
inderal for sale
buy indocin without prescription
indocin for sale
buy naprosyn without prescription
naprosyn for sale
buy pletal without prescription
pletal for sale
buy robaxin without prescription
robaxin for sale
buy voltaren without prescription
voltaren for sale

Tech Life of Recht » archive for 'Haskell'

 xmonad 0.5

  • December 16th, 2007
  • 12:57 am

xmonad 0.5 is out, and I haven’t upgraded my installation in a while. It’s pretty nice that configuration is now done in /.xmonad/xmonad.hs, then there’s no need to recompile xmonad all the time. The configuration change did require a reorganisation of my old Config.hs, so I took a look at some of the samples to see what other people did.
I ended up with something which looks like this:

xmonad

This is my xmonad.hs:
[code]
— XMonad Core
import XMonad
import XMonad.Layout
import XMonad.Operations
import qualified XMonad.StackSet as W

— GHC hierarchical libraries
import Data.Bits ((.|.))
import qualified Data.Map as M
import Graphics.X11
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras
import System.IO

— Contribs
import XMonad.Actions.CycleWS
import XMonad.Actions.SwapWorkspaces
import XMonad.Actions.Submap
import XMonad.Actions.WindowBringer
import XMonad.Actions.FloatKeys

import XMonad.Hooks.UrgencyHook
import XMonad.Layout.NoBorders
import XMonad.Layout.Tabbed
import XMonad.Layout.WindowNavigation
import XMonad.Layout.Grid
import XMonad.Layout.LayoutHints
import XMonad.Layout.Dishes
import XMonad.Util.EZConfig
import XMonad.Util.Run

import XMonad.Prompt.Shell
import XMonad.Prompt

import XMonad.Hooks.DynamicLog ( PP(..), dynamicLogWithPP, dzenColor, wrap, defaultPP )

myfont = “\”-xos4-terminus-medium-r-normal–12-120-72-72-c-60-iso8859-1\””
fgcolor = “black”
bgcolor = “white”

statusBarCmd= “dzen2 -e ” -w 660 -h 15 -ta l -xs 1 -fg ” ++ fgcolor ++ ” -bg ” ++ bgcolor ++ ” -fn ” ++ myfont

— Get ready!
main = do din <- spawnPipe statusBarCmd xmonad $ withUrgencyHook dzenUrgencyHook { args = ["-bg", "darkgreen", "-xs", "1"] } $ defaultConfig { workspaces = workspaces' , modMask = modMask' , numlockMask = 0 , layoutHook = layoutHook' , terminal = "urxvtc || urxvt" , normalBorderColor = "#dddddd" , focusedBorderColor = "#3499dd" , defaultGaps = [(15,0,0,0)] , logHook = dynamicLogWithPP $ myPP din } `additionalKeys` keys' modMask' = mod4Mask workspaces' = map show [1] ++ ["web", "mail", "chat", "code"] ++ map show [6 .. 9 :: Int] layoutHook' = configurableNavigation noNavigateBorders $ layouts layouts = Mirror tiled ||| tiled ||| Grid ||| layoutHints Full ||| Dishes 2 (1/5) ||| noBorders (tabbed shrinkText defaultTConf { fontName = myfont }) where tiled = Tall nmaster delta ratio nmaster = 2 -- The default number of windows in the master pane ratio = 1/2 -- Default proportion of screen occupied by master pane delta = 3/100 -- Percent of screen to increment by when resizing panes noFollow CrossingEvent {} = return False noFollow _ = return True keys' = [ ((modMask' .|. shiftMask, xK_d ), spawn "date | dzen2 -p 2 -xs 1") -- %! Print current date , ((modMask', xK_p), shellPrompt defaultXPConfig) ] ++ -- modMask'-[1..0] %! Switch to workspace N -- modMask'-shift-[1..0] %! Move client to workspace N [((m .|. modMask', k), windows $ f i) | (i, k) <- zip workspaces' $ [xK_1 .. xK_9] ++ [xK_0] , (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]] ++ -- modMask'-{e,r} %! Switch to physical/Xinerama screens 1 or 2 -- modMask'-shift-{e,r} %! Move client to screen 1 or 2 [((m .|. modMask', key), screenWorkspace sc >>= flip whenJust (windows . f))
| (key, sc) <- zip [xK_e, xK_w] [0..] , (f, m) <- [(W.view, 0), (W.shift, shiftMask)]] ++ [((modMask' .|. mod1Mask, k), windows $ swapWithCurrent i) | (i, k) <- zip workspaces' $ [xK_1 .. xK_9] ++ [xK_0]] -- float keys ++ [ ((modMask', xK_d ), withFocused (keysResizeWindow (-10,-10) (1,1))) , ((modMask', xK_s ), withFocused (keysResizeWindow (10,10) (1,1))) , ((modMask', xK_a ), withFocused (keysMoveWindowTo (512,384) (1, 0))) ] myPP h = defaultPP { ppCurrent = dzenColor "white" "#cd8b00" . pad , ppVisible = dzenColor "white" "#666666" . pad , ppHidden = dzenColor "black" "#cccccc" . pad , ppHiddenNoWindows = dzenColor "#999999" "#cccccc" . pad , ppWsSep = dzenColor "#bbbbbb" "#cccccc" "^r(1x18)" , ppSep = dzenColor "#bbbbbb" "#cccccc" "^r(1x18)" , ppLayout = dzenColor "black" "#cccccc" . (\ x -> case x of
“TilePrime Horizontal” ->
” ^i(/home/emertens/images/tile_horz.xpm) ”
“TilePrime Vertical” ->
” ^i(/home/emertens/images/tile_vert.xpm) ”
“Hinted Full” ->
” ^i(/home/emertens/images/fullscreen.xpm) ”
_ -> pad x
)
, ppTitle = (‘ ‘:) . escape
, ppOutput = hPutStrLn h
}
where
escape = concatMap (\x -> if x == ‘^’ then “^^” else [x])
pad = wrap ” ” ” ”
[/code]

I use a simple shell script for starting xmonad:

[code]
ssh-add ~/.ssh/id_dsa /dev/null
Esetroot /usr/share/backgrounds/warty-final-ubuntu.png
unclutter -idle 2 &
urxvtd -f -o
irxevent -d

gnome-settings-daemon &
gnome-volume-manager &

export PATH=$PATH:`dirname $0`
`dirname $0`/status &

xmonad
[/code]

Finally, the dzen2 status bar is run using this script:
[code]
#!/bin/sh

BG=white
FG=black
FONT=”-xos4-terminus-medium-r-normal–12-120-72-72-c-60-iso8859-1″

BFG=”#444″

gcpubar -i 2 -fg ‘#444’ -w 30 -h 10 | dzen2 -e ” -x 1360 -fg $FG \
-bg $BG -fn $FONT -h 15 -xs 1 &

while :; do
MEM=`memstatus.awk /proc/meminfo`
CPU=`cpustatus.awk`
DATE=`date +”%d-%m %k:%M”`

REM=`awk ‘/remaining capacity/ { print $3 }’ /proc/acpi/battery/BAT0/state`
LAST=`awk ‘/last full/ { print $4}’ /proc/acpi/battery/BAT0/info`
STATE=`awk ‘{print $2}’ /proc/acpi/ac_adapter/ADP1/state`
if [ “$STATE” = “on-line” ]; then
BAT=$(echo $REM $LAST | awk ‘{printf “Bat: %.1f%%, AC”, ($1/$2)*100’})
else
PRESENT=`awk ‘/present rate/ { print $3}’ /proc/acpi/battery/BAT0/state`
BAT=$(echo $REM $LAST $PRESENT | \
awk ‘{printf “Bat: %.1f%%, %d min”, ($1/$2)*100, ($1/$3)*60}’)
fi

LOAD=`awk ‘{print $1 ” ” $2 ” ” $3}’ /proc/loadavg`

echo “$CPU $MEM | $DATE | $BAT | $LOAD”
sleep 5
done | dzen2 -e ” -x 660 -w 700 -fg $FG -bg $BG -fn $FONT -h 15 -xs 1
[/code]

Two awk scripts are used – one for the memory usage and one for CPU frequencies. Why awk? No idea, it just seemed like a good choice at the time.

memstatus.awk:
[code]
#!/usr/bin/awk -f
BEGIN {
BG=”darkgrey”;
FG=”#444″;
WIDTH=30;
HEIGHT=10;
}

/MemTotal/ {t=$2};
/MemFree/ {f=$2};
/SwapTotal/ {st=$2};
/SwapFree/ {sf=$2};

END {
mw=int(WIDTH*(t-f)/t);
fw=WIDTH-mw;
sw=int(WIDTH*(st-sf)/st);

printf(“Mem: ^ib(1)^fg(%s)^r(%dx%d)^fg(%s)^r(%dx%d)” \
“^fg(%s)^r(2x%d)^fg(%s)^r(%dx%d)^fg(%s)^r(%dx%d)^ib(0)^fg()\n”,
FG, mw, HEIGHT,
BG, fw, HEIGHT,
“black”,
HEIGHT, BG, WIDTH-sw,
HEIGHT, FG, sw, HEIGHT);
}
[/code]

[code]
#!/usr/bin/awk -f
BEGIN {
BG=”darkgrey”
FG=”#444″
WIDTH=30
HEIGHT=10
CPUS=0

cmd = “ls /sys/devices/system/cpu”
while ((cmd | getline) > 0) {
if ($1 ~ /cpu/) {
CPUS++
}
}
close(cmd)

printf “CPU: ”
for (i=0; i < CPUS; i++) { cfn="/sys/devices/system/cpu/cpu" i "/cpufreq/scaling_cur_freq" mfn="/sys/devices/system/cpu/cpu" i "/cpufreq/scaling_max_freq" getline cf < cfn getline mf < mfn cw=int(WIDTH*(mf-cf)/mf) printf("^ib(1)^fg(%s)^r(%dx%d)^fg(%s)^r(%dx%d)^ib(0)^fg()", FG, cw, HEIGHT, BG, WIDTH-cw, HEIGHT) close(cfn) close(mfn) if (i < CPUS - 1) { printf("^ib(0)^fg()^r(5x0)^ib(1)") } } printf("\n"); } [/code]

 The xmonad experience

  • October 1st, 2007
  • 6:28 pm

I’ve been running xmonad on both my desktop computer at home and my laptop at work, and overall I’m pretty happy about it. However, I’ve had to work around some stuff:

  • There’s no fancy graphical tools like the default Ubuntu desktop. This means no network-manager, no battery monitor, and so on. For the network manager (nm-applet), I’ve used knetworkmanager – almost the same, but it works a little better. I usually just run knetworkmanager, connects to the right network, and closes it again.
  • Battery is monitored through dzen
  • For mounting and unmounting devices, something that Ubuntu did automatically, I use pmount directly.
  • I use mplayer through kplayer, a KDE mplayer wrapper, which makes it possible to run movies in a large window with the ratio preserved, something I’ve not been able to with the command line directly.

Other than that, there’s not much to it. It does attract some interest, though. Today, I held a course on Java and Web services, and someone asked me what type of Linux I ran. Not regarding the wrongness of the question, I answered “xmonad” – and there was 5 seconds silence, followed by a vague “ah…”.

 xmonad

  • June 21st, 2007
  • 10:31 pm

I’ve looked at it a couple of times, but hadn’t really had the courage to make the switch completely. What I’m talking about is xmonad, one of the smallest and simplest window managers available. I’m not sure it’s still under 500 lines of Haskell, but it’s still pretty impressive.
The concept is not new: Windows are managed completely by xmonad by tiling. This means that there is no overlapping, and there is fill keyboard control. Furthermore, it supports Xinerama, although it takes a little getting used to.
Xmonad fits right into how I think window managers should be: Simple and out of your face. The only eyecandy is a statusbar at the top of one of the screens (which you have to configure and enable yourself), and most people probably wouldn’t quite call it eyecandy – it actually just displays the text output of any command. I’ve never actually used concepts such as a desktop or manipulating the filesystem through some obscure file explorer, so I’m not really missing anything. The only thing that bothers me is that some programs are not quite designed for tiling. Mplayer is probably the best example, it doesn’t really make sense when the Mplayer window is tiled into a 1:2 format. Work is in progress to make a floating layer so that special windows can be managed outside the tiling. Until then, I’ll just have to live without Mplayer.

xmonad screenshot

 Thinking in Objects

  • April 16th, 2007
  • 9:35 pm

In relation to my post about UML, and my experiments with Haskell, I’ve realized that I jave a handicap, which I have no reason to believe isn’t also hindering a lot of other people.
I started programming quite a few years ago (on my grandmothers C64, actually, at about the age of 8). Of course, it was not methodical or anything, and it more or less remained unstructured until I started at university. One of the first things we learned was object oriented modeling with UML. I’ve talked a little about UML, but actually object orientation turns out to be a more fundamental problem.
Without any doubt, OO has helped me tremendously in the past, but I’ve realized that it’s also become a hindrance. Why? Quite simply because I can’t think of a problem without modeling it in OO terms. Some might see this as a force, which it probably is in some situations, but we live in times where language paradigms are getting mixed up – just look at Ruby and RoR, .NET 3.5 – and this means that us OO people might be getting a hard time utilizing the languages.
Of course, working with something like Haskell only makes it worse, as it contains no objects at all. There are some concepts which can be mapped, but programs are structured and modeled differently. The OO thinking has proved to me to be the biggest problem with learning Haskell. Learning a new syntax, new apis, and so on, is not much trouble, but Thinking in Functions is.

All this wouldn’t be so bad if object orientation Just Did It ™. However, just as UML doesn’t quite fit the bill anymore, OO is also not in the perfect place.
For example, how many have been immersed in a service oriented architecture, where types are defined in schema files and then mapped to classes? What behavior do these classes contain? Just about none, instead behavior is placed in auxiliary classes, often using static methods. A part of this is a language problem – Java just makes it hard to add behavior to these types, but that’s not the whole story. And even if it was, then most programmers’ mindset is not geared towards such dynamic behavior-adding – again, Ruby (on Rails) is a good example of this: Most people I know think Ruby is great, but close to everybody also thinks that using techniques as mixins have the potential to make the code very hard to manage. I’m not in a position to say whether this is true or not, but time will probably tell.
I am pretty sure, however, that one of the reasons we tend to make awesome enterprisey systems is that we’re working with some wrong paradigms. I’m in no way a fan of SOA, WS-* and so on, but for some weird reason, many of our customers are, and that more or less forces us to deal with that world. Wouldn’t it be nice if we had some way of dealing with it without jumping through all these oddly shaped hoops?

There are all kinds of suggestions as to how to get this: Tooling, languages, DSLs, and so on. But then again: Is that really the best we can do? (and just to be clear: I’m just writing what I’m thinking in the hope that I some day might either realize that I’ve already got what I want, or am able to clearly specify what it is, I’m looking for).

 Hugs error

  • February 15th, 2007
  • 1:12 am

After my initial encounters with Haskell, I thought I’d better get a more systematic introduction to the language. The myriads of wikis and tutorials is very fine, but sometimes a real book is just better. So, I ordered The Haskell School of Expression, which I’m enjoying. It’s not for the faintest of heart, but luckily most of the concepts are well-known from my time at university. It is not, however, a beginners introduction, at least not in my world.

Anyways, I’m slowly working my way through the book and the exercises, but then I hit a problem: The last exercise in chapter 10 is about making a shape follow the mouse cursor. Pretty simple stuff, if it wasn’t because Hugs complained over a case pattern which looked somewhat like this:
[code]
e <- getWindowEvent w case e of Button x True False -> — do stuff here
MouseMove (x,y) -> — do other stuff here
[/code]

Nothing fancy here, but Hugs broke down and cried
[code]
ERROR “Picture.hs”:148 – Type error in case pattern
*** Term : Button x True False
*** Type : Event
*** Does not match : Event
[/code]

Which doesn’t make much sense. I tried qualifying the type constructors, but that didn’t change anything. In the end, I had to switch to GHC, and I still have no idea about what Hugs’ problem was.

 More on Haskell

  • January 23rd, 2007
  • 5:39 pm

Ok, so I’ve managed to write an actual application in Haskell. It’s actually a rewrite of a C program (which I didn’t write myself). Even though it’s a pretty small program (it’s a wrapper for qmail-local), it’s definitely been interesting. I might even go as far as to say thay I understand monads – although I’m not going to attempt to explain them here.
It’s a little uncertain if the program got any better by rewriting it. I pretty much suck at C (way too much time spent in Java), so at least I avoid the segfaults. The Haskell program came in at 89 lines, the C program at 126, and the Haskell program actually has a bunch of extra features.
Anyways, I’m beginning to like Haskell and the way it works. If only the reference api had more examples…

 Fun with Haskell

  • January 19th, 2007
  • 2:02 pm

At JAOO 2006, I attended a session with Erik Meijer on Haskell. The session gave a very quick introduction to Haskell as a very nice functional language, and the enthusiasm of Erik Meijer on the subject only made it more interesting.
So, I’ve been messing around with Haskell for a while, without producing anything worthwhile – I’m still trying to figure out how to put the language to good use. However, I found a list of Haskell quizzes, derived from Ruby Quiz. Some of these have not yet been solved, so I sat down and began working on Splitting the Loot. After some hours, I suddenly discovered that I have a working solution – somewhat to my surprise.

Anyways, here it is – as it’s one of my first Haskell programs, I’m sure there’s lots of room for improvement. What it does is basically to find all possible combinations of a list of numbers, and then it tries to combine these combinations in order to find a valid solution:

[code]
divide :: Integer -> [Integer] -> [(Integer, [Integer])]
divide persons vals
| toInteger (length vals) < persons = error "Not enough values" | not $ mod (sum vals) persons == 0 = error "Values cannot be divided equally" | otherwise = divide'' persons vals (div (sum vals) persons) [] 1 divide'' persons vals maxval res cnt | cnt > persons = res
| otherwise =
let p = permut vals maxval
nx = findE p maxval
in divide” persons (deleteFirstsBy (==) vals nx) maxval ((cnt, nx):res) (cnt + 1)

findE [] c = error “Unable to find fitting element”
findE xs c
| sum (head xs) == c = head xs
| otherwise = findE (tail xs) c

uniq [] sorted = reverse sorted
uniq xs [] = uniq (tail xs) [head xs]
uniq xs sorted
| head xs == head sorted = uniq (tail xs) sorted
| otherwise = uniq (tail xs) (head xs:sorted)

permut :: [Integer] -> Integer -> [[Integer]]
permut nums maxval = permut’ nums [] 0 maxval

permut’ :: [Integer] -> [[Integer]] -> Int -> Integer -> [[Integer]]
permut’ nums [] _ maxval = permut’ nums (map (\x -> [x]) nums) 0 maxval
permut’ nums xs cnt maxval
| cnt + 2 > length nums = uniq (sort xs) []
| otherwise = permut’
nums
(xs ++ uniq
(sort $
foldr (++) []
[map (\ ys -> appendIfNecessary x ys nums maxval) xs | x <- nums] ) []) (cnt + 1) maxval appendIfNecessary x xs old maxval | elem x (deleteFirstsBy (==) old xs) = if (sum xs) + x > maxval
then xs
else x:xs
| otherwise = xs
[/code]