Saturday, 12 October 2013

Haskell Lens Isomorphisms

A small snippet of code I wrote to try and get my head around Van Laarhoven lenses. It shows the isomorphisms between three common representations of lenses.

{-# LANGUAGE RankNTypes #-}

-- Traditional lens as a pair of getter and setter
type Lens a b = (b -> a, b -> a -> b)

-- Lens implemented with a store comonad
data Store a b = Store { get :: a, set :: a -> b }

instance Functor (Store a) where
    fmap f (Store a ab) = Store a (f . ab)

type SLens a b = b -> Store a b

-- Van Laarhoven lens
type VLLens a b = forall g . Functor g => (a -> g a) -> (b -> g b)

-- Lens / SLens isomorphism

lensToSlens :: Lens a b -> SLens a b
lensToSlens (getter, setter) = \b -> Store (getter b) (setter b)

sLensToLens :: SLens a b -> Lens a b
sLensToLens slens = (get . slens, set . slens)

-- SLens / VLLens isomorphism

sLensToVLLens :: SLens a b -> VLLens a b
sLensToVLLens slens = \f b -> let Store a ab = slens b in fmap ab $ f a

vLLensToSLens :: VLLens a b -> SLens a b
vLLensToSLens vllens = \b -> ((flip vllens) b) (\a -> Store a id)

Thursday, 3 October 2013

Ubuntu on the Gigabyte P34G Ultrablade

In my previous post on the Gigabyte P34G I looked at my reasons for buying it and first impressions. In this post, I'm going to look at installing and setting up Ubuntu GNU/Linux on this machine.

Installation and Setup

Creating USB installation media

On another Ubuntu machine:
  • Download the Ubuntu Live CD ISO.  I started with Ubuntu 13.04, but you are probably better off to go straight to 13.10 for reasons described below.
  • Copy to USB stick using usb-creator-gtk (or dd if you're feeling more adventurous, but make sure you don't wipe your hard disk by mistake!).

BIOS settings

To get to the BIOS settings you first need to boot into Windows 8 and then do a proper shutdown (i.e. not a fastboot shutdown).  I used the pre-installed Gigabyte utility to do this as the standard Windows shutdown just went into fastboot mode.

Insert the USB stick then boot into the BIOS by holding down <F2> during startup.
BIOS settings:
  • Disable 3D Graphic Acceleration.  The X server won't start unless you do this.  I think it's getting confused about which graphics adapter to use.
  • Intel Rapid Start Technology.  Not sure if this is necessary.
  • Disable Secure Boot.  Again, not sure that it's necessary.
  • Set boot sequence to boot from the USB stick.
Boot the USB stick and select 'Install'.

Note: I originally tried installing Linux Mint 15, but could not get the installation media to boot, even with the BIOS changes described above, which was why I went with Ubuntu instead.


I deleted the Windows partition on the 256GB SSD and replaced it with:
There were two partitions for Windows restore, a small 20MB partition at the start and a larger 30GB partition at the end of the SSD.  I kept both of these for now, in case I need to restore Windows 8 for some reason.  I will probably eventually end up removing the 30GB and extending the size of /home. I also kept the EFI boot partition which is required for UEFI boot as the disk uses GPT.

If you want to dual boot Windows 8 and Ubuntu you should be able to shrink the size of the Windows partition to fit the Linux partitions in.

I partitioned the 1TB HDD as
  • 16GB for swap.  Unlikely to ever actually use this, but it's there just in case.
  • Remainder Ext4 partition to mounted as /data.


After booting for the first time I noticed that the wifi card (Intel Centrino 7260) was not detected.  After reading I determined that I needed to upgrade the Linux kernel to 3.11 (from 3.08), and possibly install some firmware binaries, to get this card to work.  I couldn't find kernel 3.11 packages for Ubuntu 13.04, but noticed that it is the standard kernel in 13.10, which is due for release in just over 2 weeks.  I decided the easiest option was probably to just upgrade to the latest development version of Ubuntu 13.10 which I did by connecting an ethernet cable to my router and running sudo upgrade-manager -d.  If you're installing from scratch, I'd recommend going directly to Ubuntu 13.10 rather than installing 13.04 first.  It may have even been officially released by the time you read this.  Installing the firmware binary was not necessary.  It must have been included either by Ubuntu or an update to the Linux kernel since the above-linked post was written.

The other thing I've noticed about wifi is that it occasionally just stops working.  It's happened maybe two or three times in the week since I've had the laptop.  It's probably a sign that the drivers aren't yet mature.  It can be easily fixed by running sudo rmmod iwlwifi; modprobe iwlwifi to remove and re-insert the wifi driver module.  Hopefully this problem will go away after some future kernel upgrade.

SSD options in fstab

Once you've got the system up there are a couple of flags you need to add to the entries for the SSD partitions in /etc/fstab:
  • Add the discard flag to enable TRIM.  The will prevent performance decreasing over time as the drive fills up.
  • Add noatime flag to avoid causing a write to the SSD every time you do a read (which will wear the SSD out much faster than necessary).
I'm suprised the Ubuntu installer doesn't set these options by default for SSD drives.


The first time I tried playing a YouTube video in Ubuntu there was no sound.  I've since noticed that the sound is now working so not sure what was going on there.


The touchpad is very sensitive to accidental palm touches, making typing a frustrating experience. You can easily disable it when necessary using  Fn-F10 key combination. You can also use synclient to configure palm detection, see e.g.  I had to use very low values (PalmMinWidth=3 PalmMinZ=1) to get it to be usable, but YMMV.  You can also use synclient to configure other settings, such as two-finger scrolling and three-finger tap for middle mouse button.

One weird thing I noticed was that the other evening, after I had been playing with BIOS settings trying to work out what the minimum changes were that were needed to get Ubuntu to boot, I booted up and found that the touchpad was no longer working.  Neither xinput nor synclient could find the touchpad at all.  I plugged in a USB mouse which worked, but nothing I tried could get the touchpad to re-appear.  Feeling frustrated, I turned off the computer and went to bed.  Next day when I started it up the touchpad was back.  No idea what happened there and hoping it doesn't happen again.


Bluetooth is provided by the Intel Centrino 7260 wifi card.  Ubuntu reports that it is working, but in a quick test I could not get it to pair up with my phone.  The phone couldn't see the laptop and neither could the laptop see the phone.  I didn't investigate this too much because I don't really have a need for it.  It may be another sign of driver immaturity for this card.


Suspend seems to work.  I have it set to suspend when I close the lid and it has so far always come back ok.  I am hoping a future Linux kernel will support Intel Rapid Start and, as mentioned previously, have left space on the SSD for it.

Still to do

Things I still need to do:
  • Install Bumblebee and the NVidia drivers to allow the GTX 760M to work with Optimus.  I'm currently not using it at all and relying on the Intel integrated graphics.  I did briefly try using the latest NVidia driver, which is supposed to have Optimus support without requiring Bumblebee, however, even after re-enabling "graphics acceleration" in the BIOS I could not get the X server to start.  I haven't had time to investigate this further.
  • I find that the hard disk occasionally spins up when I'm not using it.  This may be related to the kernel "swappiness" parameter (I have a swap partition there, but it shouldn't be using it with 16GB of RAM), or it may be due to some other activity.  Not sure yet.
  • Install XMonad instead of the Unity window manager.
  • Check out whether I can get Intel Rapid Start to work.