Fiddling with GADTs
May 16, 2013 | Filed Under Uncategorized | Leave a Comment
Check the depth of the structure:
*Main> depth T0 0 *Main> depth (Tm T0) 1 *Main> depth (Tm (Tm (Tm (Tm T0)))) 4
The function twoOfSameDepth expects both parameters to be of the same depth. If not, you get a type error.
*Main> :t twoOfSameDepth T0 T0
twoOfSameDepth T0 T0 :: Int
*Main> :t twoOfSameDepth T0 (Tm T0)
<interactive>:1:20:
Couldn't match expected type `'Z' with actual type `S n0'
Expected type: T 'Z
Actual type: T (S n0)
In the return type of a call of `Tm'
In the second argument of `twoOfSameDepth', namely `(Tm T0)'
The function secondIsPlusOne expects the second parameter to be of depth one more than the first parameter:
*Main> :t secondIsPlusOne T0 (Tm T0)
secondIsPlusOne T0 (Tm T0) :: Bool
*Main> :t secondIsPlusOne T0 (Tm (Tm T0))
<interactive>:1:25:
Couldn't match expected type `'Z' with actual type `S n0'
Expected type: T 'Z
Actual type: T (S n0)
In the return type of a call of `Tm'
In the first argument of `Tm', namely `(Tm T0)'
*Main>
In Matt’s LambdaJam talk/jam you can see how this idea can be used to help with implementing a b-tree data structure.
Create a Joomla password hash/salt database entry in Python
May 6, 2013 | Filed Under Uncategorized | Leave a Comment
Handy for manually resetting a user’s password. Tested on Joomla 2.5.
Note to self: quickly plot a shapefile using Python and basemap
April 17, 2013 | Filed Under Uncategorized | Leave a Comment
Note to self: haskell-platform needs OpenGL
March 31, 2013 | Filed Under Uncategorized | Leave a Comment
On Debian squeeze, one needs some OpenGL libraries to install haskell-platform-2012.4.0.0:
✗ 09:42:08 carlo@r500 ~/opt/haskell-platform-2012.4.0.0 $ ./configure --prefix=/home/carlo/opt/haskell-platform-2012.4.0.0_build ... checking zlib.h usability... yes checking zlib.h presence... yes checking for zlib.h... yes checking for zlibVersion in -lz... yes checking GL/gl.h usability... no checking GL/gl.h presence... no checking for GL/gl.h... no configure: error: The OpenGL C library is required
Solution:
sudo apt-get install libgl1-mesa-dev \
libglc-dev \
freeglut3-dev \
libedit-dev \
libglw1-mesa libglw1-mesa-dev
Credit: http://nathanwiegand.com/blog/2009/07/haskell-platform-on-ubuntu.html
note to self: semi-unstructured text parsing with Parsec (and an alternative)
March 10, 2013 | Filed Under Uncategorized | Leave a Comment
Managed to answer someone’s question on haskell-cafe about parsing semi-structured text with Parsec:
S. Doaitse Swierstra pointed out that the Data.List.Grouping package may be more appropriate here.
Note to self: Parsec and ‘nova list’
February 19, 2013 | Filed Under Uncategorized | Leave a Comment
Example input:
+--------------------------------------+------------------------+--------+----------------------------+ | ID | Name | Status | Networks | +--------------------------------------+------------------------+--------+----------------------------+ | 10000000-0000-0000-0000-000000000001 | vm 1 | ACTIVE | cell1=192.168.1.1 | | 10000000-0000-0000-0000-000000000002 | vm 2 | ACTIVE | cell2=192.168.1.2 | | 10000000-0000-0000-0000-000000000003 | vm 3 | ACTIVE | cell2=192.168.1.3 | | 10000000-0000-0000-0000-000000000004 | vm 4 | ACTIVE | cell1=192.168.1.4 | | 10000000-0000-0000-0000-000000000005 | vm 5 | ACTIVE | cell1=192.168.1.5 | | 10000000-0000-0000-0000-000000000006 | vm 6 | BUILD | cell1=192.168.1.6 | | 10000000-0000-0000-0000-000000000007 | vm 7 | BUILD | cell1=192.168.1.7 | | 10000000-0000-0000-0000-000000000008 | vm 8 | ACTIVE | cell2=192.168.1.8 | | 10000000-0000-0000-0000-000000000009 | vm 9 | ACTIVE | cell1=192.168.1.9 | | 10000000-0000-0000-0000-000000000010 | vm 10 | ACTIVE | cell1=192.168.1.10 | | 10000000-0000-0000-0000-000000000011 | vm 11 | ACTIVE | cell2=192.168.1.11 | | 10000000-0000-0000-0000-000000000012 | vm 12 | ACTIVE | cell2=192.168.1.12 | | 10000000-0000-0000-0000-000000000013 | vm 13 | ACTIVE | cell1=192.168.1.13 | | 10000000-0000-0000-0000-000000000014 | vm 14 | ACTIVE | cell1=192.168.1.14 | | 10000000-0000-0000-0000-000000000015 | vm 15 | ACTIVE | cell1=192.168.1.15 | | 10000000-0000-0000-0000-000000000016 | vm 16 | ACTIVE | cell2=192.168.1.16 | | 10000000-0000-0000-0000-000000000017 | vm 17 | ACTIVE | cell1=192.168.1.17 | | 10000000-0000-0000-0000-000000000018 | vm 18 | ACTIVE | cell2=192.168.1.18 | | 10000000-0000-0000-0000-000000000019 | vm 19 | ACTIVE | cell2=192.168.1.19 | | 10000000-0000-0000-0000-000000000020 | vm 20 | ACTIVE | cell1=192.168.1.20 | | 10000000-0000-0000-0000-000000000021 | vm 21 | ACTIVE | cell2=192.168.1.21 | | 10000000-0000-0000-0000-000000000022 | vm 22 | BUILD | | | 10000000-0000-0000-0000-000000000023 | vm 23 | ACTIVE | cell1=192.168.1.22 | | 10000000-0000-0000-0000-000000000024 | vm 24 | DERP | cell1=192.168.1.23 | +--------------------------------------+------------------------+--------+----------------------------+
Example run:
$ ghc --make ReadNovaList.hs && cat nova_list_output.txt | ./ReadNovaList
("10000000-0000-0000-0000-000000000001","vm 1",Active,Just (Network {networkCell = "cell1", networkIP = "192.168.1.1"}))
("10000000-0000-0000-0000-000000000002","vm 2",Active,Just (Network {networkCell = "cell2", networkIP = "192.168.1.2"}))
("10000000-0000-0000-0000-000000000003","vm 3",Active,Just (Network {networkCell = "cell2", networkIP = "192.168.1.3"}))
("10000000-0000-0000-0000-000000000004","vm 4",Active,Just (Network {networkCell = "cell1", networkIP = "192.168.1.4"}))
("10000000-0000-0000-0000-000000000005","vm 5",Active,Just (Network {networkCell = "cell1", networkIP = "192.168.1.5"}))
("10000000-0000-0000-0000-000000000006","vm 6",Building,Just (Network {networkCell = "cell1", networkIP = "192.168.1.6"}))
("10000000-0000-0000-0000-000000000007","vm 7",Building,Just (Network {networkCell = "cell1", networkIP = "192.168.1.7"}))
("10000000-0000-0000-0000-000000000008","vm 8",Active,Just (Network {networkCell = "cell2", networkIP = "192.168.1.8"}))
("10000000-0000-0000-0000-000000000009","vm 9",Active,Just (Network {networkCell = "cell1", networkIP = "192.168.1.9"}))
("10000000-0000-0000-0000-000000000010","vm 10",Active,Just (Network {networkCell = "cell1", networkIP = "192.168.1.10"}))
("10000000-0000-0000-0000-000000000011","vm 11",Active,Just (Network {networkCell = "cell2", networkIP = "192.168.1.11"}))
("10000000-0000-0000-0000-000000000012","vm 12",Active,Just (Network {networkCell = "cell2", networkIP = "192.168.1.12"}))
("10000000-0000-0000-0000-000000000013","vm 13",Active,Just (Network {networkCell = "cell1", networkIP = "192.168.1.13"}))
("10000000-0000-0000-0000-000000000014","vm 14",Active,Just (Network {networkCell = "cell1", networkIP = "192.168.1.14"}))
("10000000-0000-0000-0000-000000000015","vm 15",Active,Just (Network {networkCell = "cell1", networkIP = "192.168.1.15"}))
("10000000-0000-0000-0000-000000000016","vm 16",Active,Just (Network {networkCell = "cell2", networkIP = "192.168.1.16"}))
("10000000-0000-0000-0000-000000000017","vm 17",Active,Just (Network {networkCell = "cell1", networkIP = "192.168.1.17"}))
("10000000-0000-0000-0000-000000000018","vm 18",Active,Just (Network {networkCell = "cell2", networkIP = "192.168.1.18"}))
("10000000-0000-0000-0000-000000000019","vm 19",Active,Just (Network {networkCell = "cell2", networkIP = "192.168.1.19"}))
("10000000-0000-0000-0000-000000000020","vm 20",Active,Just (Network {networkCell = "cell1", networkIP = "192.168.1.20"}))
("10000000-0000-0000-0000-000000000021","vm 21",Active,Just (Network {networkCell = "cell2", networkIP = "192.168.1.21"}))
("10000000-0000-0000-0000-000000000022","vm 22",Building,Nothing)
("10000000-0000-0000-0000-000000000023","vm 23",Active,Just (Network {networkCell = "cell1", networkIP = "192.168.1.22"}))
("10000000-0000-0000-0000-000000000024","vm 24",StatusError "DERP",Just (Network {networkCell = "cell1", networkIP = "192.168.1.23"}))
Xfce4-xfapplet-plugin for Centos 6.3
February 12, 2013 | Filed Under Uncategorized | Leave a Comment
For some reason xfce4-xfapplet-plugin has been dropped from recent Centos/Fedora releases, as the spec file for xfce4-panel proclaims:
# xfce4-xfapplet-plugin isn't in F15
Provides: xfce4-xfapplet-plugin%{?_isa} = 0.1.0-11
Obsoletes: xfce4-xfapplet-plugin <= 0.1.0-10.fc15
This makes it basically impossible for anyone to use a Gnome2 applet on Xfce4. As a temporary work-around I have built an RPM of xfapplet-plugin on Centos 6.3 with the release number of 0.1.0-15, which gets around the Provides/Obsoletes lines:
xfce4-xfapplet-plugin-0.1.0-15.el6.x86_64.rpm
The git repo is here: https://github.com/carlohamalainen/xfce4-xfapplet-centos6.
Note to self: “cabal install libssh2″ on Debian testing
February 10, 2013 | Filed Under Uncategorized | Leave a Comment
Debian Squeeze doesn’t have a new enough libssh2 for the LibSSH2 package on hackage. So I tried the libssh library and dev package from Debian testing:
$ dpkg -l | grep -i libssh2 ii libssh2-1 1.4.2-1.1 SSH2 client-side library ii libssh2-1-dev 1.4.2-1.1 SSH2 client-side library (development headers)
However libssh2 failed to install using cabal:
$ cabal install libssh2 Resolving dependencies... Configuring libssh2-0.2.0.1... cabal: The pkg-config package libssh2 version >=1.2.8 is required but it could not be found. Failed to install libssh2-0.2.0.1 cabal: Error: some packages failed to install: libssh2-0.2.0.1 failed during the configure step. The exception was: ExitFailure 1
We can help it along by setting PKG_CONFIG_PATH so that cabal finds libssh2, and also set the extra lib/include directories so that it finds libgcrypt:
$ export PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig $ cabal install libssh2 --extra-include-dirs=/usr/include --extra-lib-dirs=/lib/x86_64-linux-gnu
Finally, compiling ssh-client.hs blew up in a weird way:
$ ghc –make ssh-client.hs
[1 of 1] Compiling Main ( ssh-client.hs, ssh-client.o )
ssh-client.hs:22:18:
Couldn't match expected type `BSL.ByteString'
with actual type `bytestring-0.9.2.1:Data.ByteString.Lazy.Internal.ByteString'
In the first argument of `BSL.putStr', namely `result'
In a stmt of a 'do' block: BSL.putStr result
In the expression:
do { channelExecute ch command;
result <- readAllChannel ch;
BSL.putStr result }
Thanks to this stackoverflow question I found out that I had two versions of the bytestring library installed on my system:
$ ghc-pkg list bytestring /opt/sw/64bit/debian/ghc-7.4.2/lib/ghc-7.4.2/package.conf.d bytestring-0.9.2.1 /home/carlo/.ghc/x86_64-linux-7.4.2/package.conf.d bytestring-0.10.0.1
and the answer was to hide the 0.10.x version:
$ ghc --make -hide-package bytestring-0.10.0.1 ssh-client.hs
Example usage:
$ ./ssh-client command carlo 192.168.1.70 22 uptime 20:04:43 up 35 days, 22:14, 0 users, load average: 0.00, 0.00, 0.00
Python SSL socket echo test with self-signed certificate
January 24, 2013 | Filed Under Uncategorized | Leave a Comment
For testing purposes it is convenient to use a self-signed certificate. Follow these instructions. You will be prompted for a password a few times:
openssl genrsa -des3 -out server.orig.key 2048 openssl rsa -in server.orig.key -out server.key openssl req -new -key server.key -out server.csr openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
Here is client.py, slightly modified from the Python 2.7.3 docs:
import socket, ssl, pprint
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Require a certificate from the server. We used a self-signed certificate
# so here ca_certs must be the server certificate itself.
ssl_sock = ssl.wrap_socket(s,
ca_certs="server.crt",
cert_reqs=ssl.CERT_REQUIRED)
ssl_sock.connect(('localhost', 10023))
print repr(ssl_sock.getpeername())
print ssl_sock.cipher()
print pprint.pformat(ssl_sock.getpeercert())
ssl_sock.write("boo!")
if False: # from the Python 2.7.3 docs
# Set a simple HTTP request -- use httplib in actual code.
ssl_sock.write("""GET / HTTP/1.0\r
Host: www.verisign.com\r\n\r\n""")
# Read a chunk of data. Will not necessarily
# read all the data returned by the server.
data = ssl_sock.read()
# note that closing the SSLSocket will also close the underlying socket
ssl_sock.close()
And here is server.py:
import socket, ssl
bindsocket = socket.socket()
bindsocket.bind(('', 10023))
bindsocket.listen(5)
def do_something(connstream, data):
print "do_something:", data
return False
def deal_with_client(connstream):
data = connstream.read()
while data:
if not do_something(connstream, data):
break
data = connstream.read()
while True:
newsocket, fromaddr = bindsocket.accept()
connstream = ssl.wrap_socket(newsocket,
server_side=True,
certfile="server.crt",
keyfile="server.key")
try:
deal_with_client(connstream)
finally:
connstream.shutdown(socket.SHUT_RDWR)
connstream.close()
Note: if you try to use the standard system ca certificates, e.g. on Debian:
ssl_sock = ssl.wrap_socket(s,
ca_certs="/etc/ssl/certs/ca-certificates.crt",
cert_reqs=ssl.CERT_REQUIRED)
then server.py explodes with:
Traceback (most recent call last):
File "server.py", line 24, in <module>
ssl_version=ssl.PROTOCOL_TLSv1)
File "/usr/lib/python2.6/ssl.py", line 338, in wrap_socket
suppress_ragged_eofs=suppress_ragged_eofs)
File "/usr/lib/python2.6/ssl.py", line 120, in __init__
self.do_handshake()
File "/usr/lib/python2.6/ssl.py", line 279, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [Errno 1] _ssl.c:490: error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number
If you specify the SSL version, e.g.
connstream = ssl.wrap_socket(newsocket,
server_side=True,
certfile="server.crt",
keyfile="server.key",
ssl_version=ssl.PROTOCOL_TLSv1)
then you can run into other problems, e.g.
Traceback (most recent call last):
File "server.py", line 27, in <module>
ssl_version=ssl.PROTOCOL_TLSv1)
File "/usr/lib64/python2.6/ssl.py", line 338, in wrap_socket
suppress_ragged_eofs=suppress_ragged_eofs)
File "/usr/lib64/python2.6/ssl.py", line 120, in __init__
self.do_handshake()
File "/usr/lib64/python2.6/ssl.py", line 279, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [Errno 1] _ssl.c:490: error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number
Installation notes: wxHaskell on Debian Squeeze
January 18, 2013 | Filed Under Uncategorized | 2 Comments
As of January 2013 I was not able to find Debian packages for wxWidgets 2.9, which is required by 0.90.0.1, so we’ll install directly from source. First grab some dependencies:
sudo apt-get install build-essential libgl1-mesa-dev libglu1-mesa-dev freeglut3-dev
Download 2.9.4 from http://www.wxwidgets.org/downloads/. Then:
tar jxf wxWidgets-2.9.4.tar.bz2 cd wxWidgets-2.9.4 ./configure --open-gl make -j 10 sudo make install
This installs to /usr/local. Make sure that wx-config reports the correct libs, e.g.
$ wx-config --libs -L/usr/local/lib -pthread -lwx_gtk2u_xrc-2.9 -lwx_gtk2u_html-2.9 -lwx_gtk2u_qa-2.9 -lwx_gtk2u_adv-2.9 -lwx_gtk2u_core-2.9 -lwx_baseu_xml-2.9 -lwx_baseu_net-2.9 -lwx_baseu-2.9
Now try to install using cabal:
cabal update cabal install wx
If the build fails with
/usr/local/include/wx-2.9/wx/gtk/bitmap.h:64:24: error: initializing argument 1 of ‘wxBitmap& wxBitmap::operator=(const wxBitmap&)’
then we need to patch a C++ file in wxc (credit for this is due to Mads Lindstrøm on comp.lang.haskell.wxhaskell.general).
cd ~/.cabal/packages/hackage.haskell.org/wxc/0.90.0.4 tar jxf wxc-0.90.0.4.tar.gz
Now edit wxc-0.90.0.4/src/cpp/eljpen.cpp and change line 159 from
* _ref = NULL;
to
_ref = NULL;
Then repackage:
tar zcvf wxc-0.90.0.4.tar.gz wxc-0.90.0.4 rm -fr wxc-0.90.0.4
Beware that the patch to wxc is under cabal’s control, so it could be lost if wxc is upgraded, etc. Finally, try to install again using:
cabal install wx
Finally, make sure that the hello world example works:
module Main where
import Graphics.UI.WX
main :: IO ()
main = start hello
hello :: IO ()
hello = do
f <- frame 1
quit <- button f 1
set f [layout := widget quit]
Note: if cabal install wx fails with
src/cpp/glcanvas.cpp:43:60: error: ‘wxGLContext’ has not been declared
src/cpp/glcanvas.cpp:102:1: error: ‘wxGLContext’ does not name a type
src/cpp/glcanvas.cpp:109:1: error: ‘wxGLContext’ does not name a type
src/cpp/glcanvas.cpp:116:1: error: ‘wxGLContext’ was not declared in this scope
src/cpp/glcanvas.cpp:116:1: error: ‘self’ was not declared in this scope
src/cpp/glcanvas.cpp:116:1: error: expected primary-expression before ‘void’
src/cpp/glcanvas.cpp:116:1: error: expression list treated as compound expression in initializer [-fpermissive]
src/cpp/glcanvas.cpp:117:1: error: expected ‘,’ or ‘;’ before ‘{’ token
cabal: Error: some packages failed to install:
then your system is missing OpenGL libraries (this is not a bug in wx). Double-check the configure output of wxWidgets.