Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I remove boilerplate when writing overloaded strings?

Given the following code:

{-# LANGUAGE OverloadedStrings #-}

newtype Firstname = Firstname String deriving (Eq, Show)
instance IsString Firstname where fromString = Firstname

newtype Lastname = Lastname String deriving (Eq, Show)
instance IsString Lastname where fromString = Lastname

data Person = Person { firstname :: Firstname, lastname :: Lastname, age :: Int } deriving Show

I'd like to remove the boilerplate around creating strongly-typed strings. Is is possible to use Template Haskell (or some other means) to achieve this?

eg something like:

{-# LANGUAGE OverloadedStrings, TemplateHaskell #-}

$(strongString ''Firstname)
$(strongString ''Lastname)

data Person = Person { firstname :: Firstname, lastname :: Lastname, age :: Int } deriving Show
like image 203
Darren Avatar asked Jun 15 '13 17:06

Darren


1 Answers

Use GeneralizedNewtypeDeriving and derive the IsString instance for Firstname and Lastname. A sample code for your example follows

{-# LANGUAGE OverloadedStrings, GeneralizedNewtypeDeriving #-}
import Data.String

newtype Firstname = Firstname String deriving (Eq, Show, IsString)

newtype Lastname = Lastname String deriving (Eq, Show, IsString)

data Person = Person { firstname :: Firstname
                     , lastname :: Lastname
                     , age :: Int
                     }

foo = Person "hello" "world" 10

You can use TH to write a similar function which you want but it is not worth the effort while keeping those functions in a separate module and then importing them here.

like image 88
Satvik Avatar answered Oct 30 '22 10:10

Satvik