https://wiki.haskell.org/api.php?action=feedcontributions&user=Jalexanderdatkins&feedformat=atomHaskellWiki - User contributions [en]2015-09-04T23:51:01ZUser contributionsMediaWiki 1.19.14+dfsg-1https://wiki.haskell.org/User:JalexanderdatkinsUser:Jalexanderdatkins2012-11-13T12:19:24Z<p>Jalexanderdatkins: sandbox</p>
<hr />
<div>Sandbox<br />
<br />
== -- ==<br />
<br />
Starts a single-line comment, unless immediately followed by an operator character other than <hask>-</hask>:<br />
<br />
<haskell><br />
main = print "hello world" -- this is a comment<br />
--this is a comment as well<br />
---this too<br />
foobar --+ this_is_the_second_argument_of_the_dash_dash_plus_operator<br />
</haskell><br />
<br />
The multi-line variant for comments is <hask>{- comment -}</hask>.</div>Jalexanderdatkinshttps://wiki.haskell.org/User_talk:Ashley_YUser talk:Ashley Y2012-08-31T14:44:56Z<p>Jalexanderdatkins: /* operators look like comments in syntax highlighting */</p>
<hr />
<div>Please also email me after putting something on this page. &mdash;[[User:Ashley Y|Ashley Y]] 02:49, 26 January 2012 (UTC)<br />
<br />
== Math Content ==<br />
<br />
Hi Ashley. I notice you are a sysop for haskellwiki. I'm not sure if this is a good place to ask this, but do you know if there is a reason why math support is not enabled for this wiki? I was planning to add some simple math background for some things and would have liked it to show appropriately. (If it is just because no one was sure on how to configure it, I'd be happy to tell what I had to do for my personal home wiki (same software)). [[User:BrettGiles|BrettGiles]] 22:16, 25 February 2006 (UTC)<br />
<br />
:Now switched on. If it's not showing up on a page, purge the page by adding <tt>&amp;action=purge</tt> to the end of the URL. &mdash;[[User:Ashley Y|Ashley Y]] 00:20, 27 February 2006 (UTC)<br />
<br />
:: Thank you - works perfectly. [[User:BrettGiles|BrettGiles]] 18:15, 27 February 2006 (UTC)<br />
<br />
== haskell.org skin? ==<br />
<br />
Hi Ashley. I hope you're the right person to ask about this. I'm currently setting up a wiki, and I was wondering how you got haskellwiki looking like it does? I really hate the wikipedia look, and I'd like something nice and simple I could tweak. I understand that you can get skins for mediawiki - is the haskell.org look available in this form? - [[User:MikeDodds|MikeDodds]] 12:33, 1 March 2006 (UTC)<br />
<br />
:I suppose I should publish the skin file somehow. I'm not sure the best way. &mdash;[[User:Ashley Y|Ashley Y]] 09:44, 25 March 2006 (UTC)<br />
<br />
:OK, see [[HaskellWiki:Site software]]. &mdash;[[User:Ashley Y|Ashley Y]] 01:15, 20 September 2006 (UTC)<br />
<br />
== [[Libraries and tools]] copyright status ==<br />
<br />
Dear Ashley Y,<br />
<br />
I saw that the page [[Libraries and tools/Genetic programming]] got a <nowiki>{{unknown copyright}}</nowiki> mark in the recent days during the moving to its own separate page. This mark asks me to resolve the copyright status.<br />
<br />
It was me who wrote the content of this page ([http://www.haskell.org/haskellwiki/?title=Libraries_and_tools&diff=2265&oldid=2252 here is the diff page showing this]) in February, so I thought it need not be licenced explicitly, it is automatically licenced under [[HaskellWiki:Licensing]].<br />
<br />
Have I to do something?<br />
<br />
Tank You very much in advance<br />
<br />
Best wishes<br />
<br />
[[User:EndreyMark|EndreyMark]] 12:32, 24 March 2006 (UTC)<br />
<br />
:Great, go ahead and remove the "unknown copyright" label. &mdash;[[User:Ashley Y|Ashley Y]] 09:42, 25 March 2006 (UTC)<br />
<br />
:Thank You, I have done it. [[User:EndreyMark|EndreyMark]] 18:05, 25 March 2006 (UTC)<br />
<br />
== Deletion of [[Continuation passing style]] ==<br />
<br />
Dear Ashley,<br />
<br />
Acidentally, I have created a [[Continuation passing style]] page superfluously.<br />
Because a [[Continuation]] article exists already, I suppose the superfluous empty page should be deleted, because its existence can be confusing (e.g. editors linking word "[[Continuation passing style]]" will not get a warning red link any more, but a misleading empty page). I cannot delete the page (only empty it, but it is not enough).<br />
<br />
Thank You in advance<br />
<br />
[[User:EndreyMark|EndreyMark]] 08:14, 27 October 2006 (UTC)<br />
<br />
:I made it a redirect instead. &mdash;[[User:Ashley Y|Ashley Y]] 18:44, 31 October 2006 (UTC)<br />
<br />
== Interwiki map ==<br />
<br />
Hi: could you add some stuff to the interwiki map? In [[Haste]], I was trying to interwiki to the English Wikipedia using the usual <nowiki>[[wikipedia:Scintilla]]</nowiki> interwiki link, but it didn't work (nor did en:, or wiki: - which just took one to c2.com). [[User:Gwern|Gwern]]<br />
<br />
== Same logo, less bytes ==<br />
<br />
If you're interested in using it, I shaved 407 bytes off the logo in the upper-left-hand corner of the wiki. It's [[:Image:Haskellwiki_logo_small.png|uploaded here]]. [[User:Olathe|Olathe]] 00:33, 12 August 2008 (UTC)<br />
<br />
== Latex upgrade ==<br />
While testing Pandoc's conversion of LaTeX to MediaWiki markup, I noticed some bugs. Compare [[User:Gwern/kenn]] to [https://secure.wikimedia.org/wikipedia/en/wiki/User:Gwern/kenn https://secure.wikimedia.org/wikipedia/en/wiki/User:Gwern/kenn]. The haskell.org version features many ugly red sections like '<nowiki>Failed to parse (unknown function\begin): \begin{array}{rclcl} \phi & ::= & P(t_1, \cdots, t_n) \\ & \mid & \neg\phi \\ & \mid & \phi_1 \Rightarrow \phi_2 \\ & \mid & TT & \mid & FF \\ & \mid & \phi_1 \wedge \phi_2 & \mid & \phi_1 \vee \phi_2 \\ & \mid & \forall x.\, \phi & \mid & \exists x.\, \phi \end{array}</nowiki>'.<br />
<br />
John MacFarlane, Pandoc's author, thinks this is because of outdated addons to MediaWiki or MediaWiki itself; this is consistent with the same source text not producing those errors on the English Wikipedia. Could you fix this? --[[User:Gwern|Gwern]] 10:46, 6 September 2008 (UTC)<br />
<br />
== Request for MediaWiki Upgrade ==<br />
I request that you update the MediaWiki software to a more recent version. Thanks in advance. &mdash;[[User:HowardBGolden|HowardBGolden]] 08:17, 4 October 2008 (UTC)<br />
<br />
:This will require a larger update to the machine that runs HaskellWiki, which I can't do easily. &mdash;[[User:Ashley Y|Ashley Y]] 07:56, 18 August 2009 (UTC)<br />
<br />
== Spam ==<br />
An indef block of http://www.haskell.org/haskellwiki/?title=Special:Contributions&target=D0rk23 please. --[[User:Gwern|Gwern]] 12:22, 7 July 2009 (UTC)<br />
<br />
:Done. &mdash;[[User:Ashley Y|Ashley Y]] 22:16, 6 August 2009 (UTC)<br />
<br />
----<br />
<br />
Block of http://www.haskell.org/haskellwiki/?title=Special:Contributions&target=HelenGarcia please. --[[User:Gwern|Gwern]] 01:09, 9 April 2010 (UTC)<br />
<br />
:And [[User:Carolin]]. --[[User:Gwern|Gwern]] 01:12, 9 April 2010 (UTC)<br />
<br />
== Sitenotice ==<br />
[[MediaWiki:Sitenotice]] needs editing badly; I have seen many people assume that no accounts are being created. Any change in wording would be better - how about 'To request an account, click here'? --[[User:Gwern|Gwern]] 13:36, 6 August 2009 (UTC)<br />
<br />
:Is this better? &mdash;[[User:Ashley Y|Ashley Y]] 22:14, 6 August 2009 (UTC)<br />
<br />
::Yes, loads. --[[User:Gwern|Gwern]] 01:09, 7 August 2009 (UTC)<br />
<br />
== Spam & account registration ==<br />
<br />
It has been a while since the spam became a real issue and account registration was disabled. Creating accounts has proven kind of draining for me, even when I pushed byorgey up to be listed first. Is there any chance we could re-enable registration and see whether the spammers have given up? We are surely driving away potential contributors with such a laborious sign-up procedure. --[[User:Gwern|Gwern]] 00:38, 27 February 2010 (UTC)<br />
<br />
:OK, I've opened it up again. Hopefully we'll be OK. &mdash;[[User:Ashley Y|Ashley Y]] 02:38, 16 March 2010 (UTC)<br />
<br />
::Well, we were pretty fine for the last couple months, but then a few dozen/hundred spam accounts got registered...<br />
::It seems to me we need an active admin. I nominate myself. The discussion on -cafe about new admins [http://www.mail-archive.com/haskell-cafe@haskell.org/msg60954.html petered out] last time (Peterson never replied to me), but now it's a little more urgent. --[[User:Gwern|Gwern]] 01:21, 12 July 2010 (UTC)<br />
<br />
:::We're in the process of moving to a new server running Debian and MediaWiki 1.12. &mdash;[[User:Ashley Y|Ashley Y]] 01:44, 12 July 2010 (UTC)<br />
<br />
::::Which will no doubt help. But spammers won't block themselves. --[[User:Gwern|Gwern]] 03:43, 12 July 2010 (UTC)<br />
<br />
:::::I think MediaWiki 1.12 has some extensions that will help. &mdash;[[User:Ashley Y|Ashley Y]] 03:58, 12 July 2010 (UTC)<br />
<br />
:What's the process for approving people to be admin? Should I ping the Cafe list about it? &mdash;[[User:Ashley Y|Ashley Y]] 17:36, 12 July 2010 (UTC)<br />
<br />
::I don't think there is any process. I linked an email in which I suggested several people for adminship (including myself), and no one objected to any of my choices, which is pretty much how the English Wikipedia did things in the early days. --[[User:Gwern|Gwern]] 00:27, 13 July 2010 (UTC)<br />
<br />
=== Steady spam ===<br />
<br />
Any chance we could turn on email autoconfirmation? That was recently switched on for the LessWrong wiki, which was suffering from a similar level of spam by apparently the same exact spammers (down to usernames and page content, sometimes), and has worked wonders. --[[User:Gwern|Gwern]] 17:17, 14 December 2011 (UTC)<br />
<br />
:I'll have a look over the weekend. I'm not sure if I have root access to the box, but I'll see what I can do. &mdash;[[User:Ashley Y|Ashley Y]] 02:47, 26 January 2012 (UTC)<br />
<br />
:OK, I switched on $wgEmailConfirmToEdit. &mdash;[[User:Ashley Y|Ashley Y]] 01:55, 30 January 2012 (UTC)<br />
<br />
::Thanks. Hasn't made too dramatic a dent, but it's early days yet. --[[User:Gwern|Gwern]] 00:04, 2 February 2012 (UTC)<br />
<br />
== Error in Hawiki.php ==<br />
<br />
I'm not sure if this is really causing any issues, but it's kind of alarming: If you look closely, you'll see that (under the hawiki skin) all the pages include essentially this HTML in teh <code>head</code>:<br />
<pre-html><br />
<script type="text/javascript" src="/haskellwiki/index.php?title=-&amp;action=raw&amp;smaxage=0&amp;gen=js&amp;useskin=hawiki"><br />
&lt;!-- site js --><br />
</script><br />
</pre-html><br />
<br />
Unfortunately, what comes back from MediaWiki when the browser asks for http://haskell.org/haskellwiki/index.php?title=-&action=raw&smaxage=0&gen=js&useskin=hawiki is not JavasSript, but instead this:<br />
<pre-html style="white-space: pre-wrap"><br />
<br /><br />
<b>Catchable fatal error</b>: Argument 1 passed to SkinHawiki::initPage() must be an instance of OutputPage, instance of StubObject given, called in /usr/share/mediawiki/includes/RawPage.php on line 165 and defined in <b>/srv/web/wikidata/skin/Hawiki.php</b> on line <b>23</b><br /><br />
</pre><br />
<br />
Similarly, there is a piece of CSS like this:<br />
<pre-css><br />
@import "/haskellwiki/index.php?title=-&action=raw&gen=css&maxage=18000&smaxage=0&useskin=hawiki";<br />
</pre-css><br />
and the same error occurs when the browser asks for http://haskell.org/haskellwiki/index.php?title=-&action=raw&gen=css&maxage=18000&smaxage=0&useskin=hawiki.<br />
<br />
P.S. It's also kind of annoying that most of the custom CSS is in wikistatic ([http://haskell.org/wikistatic/skins//hawiki/main.css hawiki/main.css]), rather than in [[MediaWiki:Common.css]] and [[MediaWiki:Hawiki.css]]. Though, now that I look really closely, I do see that [[MediaWiki:Common.css|Common.css]] not only exists, but even contains a few rules, which is nice!<br />
<br />
P.P.S. It's too bad we don't have the MediaWiki feature whereby users get to extend the skins by putting CSS/JS in subpages of their userpage...<br />
<br />
--[[User:SamB|SamB]] 05:45, 8 June 2011 (UTC)<br />
<br />
== I broke &lt;hask&gt; tags ==<br />
<br />
I'm guessing from your signature on [[HaskellWiki:Syntax_highlighting]] that you are the person to tell about this. See [[User:benmachine]]: it seems that leaving a comment tag unclosed inside a &lt;hask&gt; breaks syntax highlighting forever.<br />
--[[User:Benmachine|benmachine]] 19:31, 9 June 2011 (UTC)<br />
<br />
== operators look like comments in syntax highlighting ==<br />
<br />
Ashley,<br />
<br />
[[User talk:Henk-Jan van Tuyl|Henk-Jan van Tuyl]] and [[User talk:Jalexanderdatkins|myself]] have been discussing a teeny tiny issue with the syntax highlighter, which is that a user-defined operator beginning with the characters -- incorrectly causes the rest of the line to be formatted as a comment. This is immaterial everywhere except in the one example which is written on the wiki to show that it is not in fact a comment, which can be found at [[Keywords#--]]. What I have done there is to insert a zero-width space (a unicode character) between the two hyphens, but Henk-Jan van Tuyl reports that the zero-width space appears as a rectangle with his combination of browser/operating system. If you view an old version of the page (before my edit) you will see what the syntax highlighter was doing before that.<br />
<br />
Could the syntax highlighter be modified so that user-defined operators beginning with -- are not treated as one-line comments, or is it not worth it? (I suppose I could take that last line out and put it in a &lt;pre&gt; or something.) It just bothers me that the syntax highlighter appears to be contradicting the very point that the example is trying to make.<br />
<br />
Yours,<br />
<br />
[[User:Jalexanderdatkins|jalexanderdatkins]] 23:37, 5 August 2012 (UTC)<br />
<br />
PS: Many thanks for everything you have done for the haskellwiki in your time. You are making the world a better place. [[User:Jalexanderdatkins|jalexanderdatkins]] 23:38, 5 August 2012 (UTC)</div>Jalexanderdatkinshttps://wiki.haskell.org/User_talk:Ashley_YUser talk:Ashley Y2012-08-05T23:38:58Z<p>Jalexanderdatkins: /* operators look like comments in syntax highlighting */</p>
<hr />
<div>Please also email me after putting something on this page. &mdash;[[User:Ashley Y|Ashley Y]] 02:49, 26 January 2012 (UTC)<br />
<br />
== Math Content ==<br />
<br />
Hi Ashley. I notice you are a sysop for haskellwiki. I'm not sure if this is a good place to ask this, but do you know if there is a reason why math support is not enabled for this wiki? I was planning to add some simple math background for some things and would have liked it to show appropriately. (If it is just because no one was sure on how to configure it, I'd be happy to tell what I had to do for my personal home wiki (same software)). [[User:BrettGiles|BrettGiles]] 22:16, 25 February 2006 (UTC)<br />
<br />
:Now switched on. If it's not showing up on a page, purge the page by adding <tt>&amp;action=purge</tt> to the end of the URL. &mdash;[[User:Ashley Y|Ashley Y]] 00:20, 27 February 2006 (UTC)<br />
<br />
:: Thank you - works perfectly. [[User:BrettGiles|BrettGiles]] 18:15, 27 February 2006 (UTC)<br />
<br />
== haskell.org skin? ==<br />
<br />
Hi Ashley. I hope you're the right person to ask about this. I'm currently setting up a wiki, and I was wondering how you got haskellwiki looking like it does? I really hate the wikipedia look, and I'd like something nice and simple I could tweak. I understand that you can get skins for mediawiki - is the haskell.org look available in this form? - [[User:MikeDodds|MikeDodds]] 12:33, 1 March 2006 (UTC)<br />
<br />
:I suppose I should publish the skin file somehow. I'm not sure the best way. &mdash;[[User:Ashley Y|Ashley Y]] 09:44, 25 March 2006 (UTC)<br />
<br />
:OK, see [[HaskellWiki:Site software]]. &mdash;[[User:Ashley Y|Ashley Y]] 01:15, 20 September 2006 (UTC)<br />
<br />
== [[Libraries and tools]] copyright status ==<br />
<br />
Dear Ashley Y,<br />
<br />
I saw that the page [[Libraries and tools/Genetic programming]] got a <nowiki>{{unknown copyright}}</nowiki> mark in the recent days during the moving to its own separate page. This mark asks me to resolve the copyright status.<br />
<br />
It was me who wrote the content of this page ([http://www.haskell.org/haskellwiki/?title=Libraries_and_tools&diff=2265&oldid=2252 here is the diff page showing this]) in February, so I thought it need not be licenced explicitly, it is automatically licenced under [[HaskellWiki:Licensing]].<br />
<br />
Have I to do something?<br />
<br />
Tank You very much in advance<br />
<br />
Best wishes<br />
<br />
[[User:EndreyMark|EndreyMark]] 12:32, 24 March 2006 (UTC)<br />
<br />
:Great, go ahead and remove the "unknown copyright" label. &mdash;[[User:Ashley Y|Ashley Y]] 09:42, 25 March 2006 (UTC)<br />
<br />
:Thank You, I have done it. [[User:EndreyMark|EndreyMark]] 18:05, 25 March 2006 (UTC)<br />
<br />
== Deletion of [[Continuation passing style]] ==<br />
<br />
Dear Ashley,<br />
<br />
Acidentally, I have created a [[Continuation passing style]] page superfluously.<br />
Because a [[Continuation]] article exists already, I suppose the superfluous empty page should be deleted, because its existence can be confusing (e.g. editors linking word "[[Continuation passing style]]" will not get a warning red link any more, but a misleading empty page). I cannot delete the page (only empty it, but it is not enough).<br />
<br />
Thank You in advance<br />
<br />
[[User:EndreyMark|EndreyMark]] 08:14, 27 October 2006 (UTC)<br />
<br />
:I made it a redirect instead. &mdash;[[User:Ashley Y|Ashley Y]] 18:44, 31 October 2006 (UTC)<br />
<br />
== Interwiki map ==<br />
<br />
Hi: could you add some stuff to the interwiki map? In [[Haste]], I was trying to interwiki to the English Wikipedia using the usual <nowiki>[[wikipedia:Scintilla]]</nowiki> interwiki link, but it didn't work (nor did en:, or wiki: - which just took one to c2.com). [[User:Gwern|Gwern]]<br />
<br />
== Same logo, less bytes ==<br />
<br />
If you're interested in using it, I shaved 407 bytes off the logo in the upper-left-hand corner of the wiki. It's [[:Image:Haskellwiki_logo_small.png|uploaded here]]. [[User:Olathe|Olathe]] 00:33, 12 August 2008 (UTC)<br />
<br />
== Latex upgrade ==<br />
While testing Pandoc's conversion of LaTeX to MediaWiki markup, I noticed some bugs. Compare [[User:Gwern/kenn]] to [https://secure.wikimedia.org/wikipedia/en/wiki/User:Gwern/kenn https://secure.wikimedia.org/wikipedia/en/wiki/User:Gwern/kenn]. The haskell.org version features many ugly red sections like '<nowiki>Failed to parse (unknown function\begin): \begin{array}{rclcl} \phi & ::= & P(t_1, \cdots, t_n) \\ & \mid & \neg\phi \\ & \mid & \phi_1 \Rightarrow \phi_2 \\ & \mid & TT & \mid & FF \\ & \mid & \phi_1 \wedge \phi_2 & \mid & \phi_1 \vee \phi_2 \\ & \mid & \forall x.\, \phi & \mid & \exists x.\, \phi \end{array}</nowiki>'.<br />
<br />
John MacFarlane, Pandoc's author, thinks this is because of outdated addons to MediaWiki or MediaWiki itself; this is consistent with the same source text not producing those errors on the English Wikipedia. Could you fix this? --[[User:Gwern|Gwern]] 10:46, 6 September 2008 (UTC)<br />
<br />
== Request for MediaWiki Upgrade ==<br />
I request that you update the MediaWiki software to a more recent version. Thanks in advance. &mdash;[[User:HowardBGolden|HowardBGolden]] 08:17, 4 October 2008 (UTC)<br />
<br />
:This will require a larger update to the machine that runs HaskellWiki, which I can't do easily. &mdash;[[User:Ashley Y|Ashley Y]] 07:56, 18 August 2009 (UTC)<br />
<br />
== Spam ==<br />
An indef block of http://www.haskell.org/haskellwiki/?title=Special:Contributions&target=D0rk23 please. --[[User:Gwern|Gwern]] 12:22, 7 July 2009 (UTC)<br />
<br />
:Done. &mdash;[[User:Ashley Y|Ashley Y]] 22:16, 6 August 2009 (UTC)<br />
<br />
----<br />
<br />
Block of http://www.haskell.org/haskellwiki/?title=Special:Contributions&target=HelenGarcia please. --[[User:Gwern|Gwern]] 01:09, 9 April 2010 (UTC)<br />
<br />
:And [[User:Carolin]]. --[[User:Gwern|Gwern]] 01:12, 9 April 2010 (UTC)<br />
<br />
== Sitenotice ==<br />
[[MediaWiki:Sitenotice]] needs editing badly; I have seen many people assume that no accounts are being created. Any change in wording would be better - how about 'To request an account, click here'? --[[User:Gwern|Gwern]] 13:36, 6 August 2009 (UTC)<br />
<br />
:Is this better? &mdash;[[User:Ashley Y|Ashley Y]] 22:14, 6 August 2009 (UTC)<br />
<br />
::Yes, loads. --[[User:Gwern|Gwern]] 01:09, 7 August 2009 (UTC)<br />
<br />
== Spam & account registration ==<br />
<br />
It has been a while since the spam became a real issue and account registration was disabled. Creating accounts has proven kind of draining for me, even when I pushed byorgey up to be listed first. Is there any chance we could re-enable registration and see whether the spammers have given up? We are surely driving away potential contributors with such a laborious sign-up procedure. --[[User:Gwern|Gwern]] 00:38, 27 February 2010 (UTC)<br />
<br />
:OK, I've opened it up again. Hopefully we'll be OK. &mdash;[[User:Ashley Y|Ashley Y]] 02:38, 16 March 2010 (UTC)<br />
<br />
::Well, we were pretty fine for the last couple months, but then a few dozen/hundred spam accounts got registered...<br />
::It seems to me we need an active admin. I nominate myself. The discussion on -cafe about new admins [http://www.mail-archive.com/haskell-cafe@haskell.org/msg60954.html petered out] last time (Peterson never replied to me), but now it's a little more urgent. --[[User:Gwern|Gwern]] 01:21, 12 July 2010 (UTC)<br />
<br />
:::We're in the process of moving to a new server running Debian and MediaWiki 1.12. &mdash;[[User:Ashley Y|Ashley Y]] 01:44, 12 July 2010 (UTC)<br />
<br />
::::Which will no doubt help. But spammers won't block themselves. --[[User:Gwern|Gwern]] 03:43, 12 July 2010 (UTC)<br />
<br />
:::::I think MediaWiki 1.12 has some extensions that will help. &mdash;[[User:Ashley Y|Ashley Y]] 03:58, 12 July 2010 (UTC)<br />
<br />
:What's the process for approving people to be admin? Should I ping the Cafe list about it? &mdash;[[User:Ashley Y|Ashley Y]] 17:36, 12 July 2010 (UTC)<br />
<br />
::I don't think there is any process. I linked an email in which I suggested several people for adminship (including myself), and no one objected to any of my choices, which is pretty much how the English Wikipedia did things in the early days. --[[User:Gwern|Gwern]] 00:27, 13 July 2010 (UTC)<br />
<br />
=== Steady spam ===<br />
<br />
Any chance we could turn on email autoconfirmation? That was recently switched on for the LessWrong wiki, which was suffering from a similar level of spam by apparently the same exact spammers (down to usernames and page content, sometimes), and has worked wonders. --[[User:Gwern|Gwern]] 17:17, 14 December 2011 (UTC)<br />
<br />
:I'll have a look over the weekend. I'm not sure if I have root access to the box, but I'll see what I can do. &mdash;[[User:Ashley Y|Ashley Y]] 02:47, 26 January 2012 (UTC)<br />
<br />
:OK, I switched on $wgEmailConfirmToEdit. &mdash;[[User:Ashley Y|Ashley Y]] 01:55, 30 January 2012 (UTC)<br />
<br />
::Thanks. Hasn't made too dramatic a dent, but it's early days yet. --[[User:Gwern|Gwern]] 00:04, 2 February 2012 (UTC)<br />
<br />
== Error in Hawiki.php ==<br />
<br />
I'm not sure if this is really causing any issues, but it's kind of alarming: If you look closely, you'll see that (under the hawiki skin) all the pages include essentially this HTML in teh <code>head</code>:<br />
<pre-html><br />
<script type="text/javascript" src="/haskellwiki/index.php?title=-&amp;action=raw&amp;smaxage=0&amp;gen=js&amp;useskin=hawiki"><br />
&lt;!-- site js --><br />
</script><br />
</pre-html><br />
<br />
Unfortunately, what comes back from MediaWiki when the browser asks for http://haskell.org/haskellwiki/index.php?title=-&action=raw&smaxage=0&gen=js&useskin=hawiki is not JavasSript, but instead this:<br />
<pre-html style="white-space: pre-wrap"><br />
<br /><br />
<b>Catchable fatal error</b>: Argument 1 passed to SkinHawiki::initPage() must be an instance of OutputPage, instance of StubObject given, called in /usr/share/mediawiki/includes/RawPage.php on line 165 and defined in <b>/srv/web/wikidata/skin/Hawiki.php</b> on line <b>23</b><br /><br />
</pre><br />
<br />
Similarly, there is a piece of CSS like this:<br />
<pre-css><br />
@import "/haskellwiki/index.php?title=-&action=raw&gen=css&maxage=18000&smaxage=0&useskin=hawiki";<br />
</pre-css><br />
and the same error occurs when the browser asks for http://haskell.org/haskellwiki/index.php?title=-&action=raw&gen=css&maxage=18000&smaxage=0&useskin=hawiki.<br />
<br />
P.S. It's also kind of annoying that most of the custom CSS is in wikistatic ([http://haskell.org/wikistatic/skins//hawiki/main.css hawiki/main.css]), rather than in [[MediaWiki:Common.css]] and [[MediaWiki:Hawiki.css]]. Though, now that I look really closely, I do see that [[MediaWiki:Common.css|Common.css]] not only exists, but even contains a few rules, which is nice!<br />
<br />
P.P.S. It's too bad we don't have the MediaWiki feature whereby users get to extend the skins by putting CSS/JS in subpages of their userpage...<br />
<br />
--[[User:SamB|SamB]] 05:45, 8 June 2011 (UTC)<br />
<br />
== I broke &lt;hask&gt; tags ==<br />
<br />
I'm guessing from your signature on [[HaskellWiki:Syntax_highlighting]] that you are the person to tell about this. See [[User:benmachine]]: it seems that leaving a comment tag unclosed inside a &lt;hask&gt; breaks syntax highlighting forever.<br />
--[[User:Benmachine|benmachine]] 19:31, 9 June 2011 (UTC)<br />
<br />
== operators look like comments in syntax highlighting ==<br />
<br />
Ashley,<br />
<br />
[[User talk:Henk-Jan van Tuyl|Henk-Jan van Tuyl]] and [[User talk:Jalexanderdatkins|myself]] have been discussing a teeny tiny issue with the syntax highlighter, which is that a user-defined operator beginning with the characters -- incorrectly causes the rest of the line to be formatted as a comment. This is immaterial everywhere except in the one example which is written on the wiki to show that it is not in fact a comment, which can be found at [[Keywords#--]]. What I have done there is to insert a zero-width space (a unicode character) between the two hyphens, but Henk-Jan van Tuyl reports that the zero-width space appears as a rectangle with his combination of browser/operating system. If you view an old version of the page (before my edit) you will see what the syntax highlighter was doing before that.<br />
<br />
Could the syntax highlighter be modified so that user-defined operators beginning with -- are not treated as one-line comments, or is it not worth it? (I suppose I could take that last line out and put it in a &lt;pre&gt; or something.) It just bothers me that the syntax highlighter appears to be contradicting the very point that the example is trying to make.<br />
<br />
Yours,<br />
<br />
[[User:Jalexanderdatkins|jalexanderdatkins]] 23:37, 5 August 2012 (UTC)<br />
<br />
<br />
PS: Many thanks for everything you have done for the haskellwiki in your time. You are making the world a better place. [[User:Jalexanderdatkins|jalexanderdatkins]] 23:38, 5 August 2012 (UTC)</div>Jalexanderdatkinshttps://wiki.haskell.org/User_talk:Ashley_YUser talk:Ashley Y2012-08-05T23:37:44Z<p>Jalexanderdatkins: /* operators look like comments in syntax highlighting */ new section</p>
<hr />
<div>Please also email me after putting something on this page. &mdash;[[User:Ashley Y|Ashley Y]] 02:49, 26 January 2012 (UTC)<br />
<br />
== Math Content ==<br />
<br />
Hi Ashley. I notice you are a sysop for haskellwiki. I'm not sure if this is a good place to ask this, but do you know if there is a reason why math support is not enabled for this wiki? I was planning to add some simple math background for some things and would have liked it to show appropriately. (If it is just because no one was sure on how to configure it, I'd be happy to tell what I had to do for my personal home wiki (same software)). [[User:BrettGiles|BrettGiles]] 22:16, 25 February 2006 (UTC)<br />
<br />
:Now switched on. If it's not showing up on a page, purge the page by adding <tt>&amp;action=purge</tt> to the end of the URL. &mdash;[[User:Ashley Y|Ashley Y]] 00:20, 27 February 2006 (UTC)<br />
<br />
:: Thank you - works perfectly. [[User:BrettGiles|BrettGiles]] 18:15, 27 February 2006 (UTC)<br />
<br />
== haskell.org skin? ==<br />
<br />
Hi Ashley. I hope you're the right person to ask about this. I'm currently setting up a wiki, and I was wondering how you got haskellwiki looking like it does? I really hate the wikipedia look, and I'd like something nice and simple I could tweak. I understand that you can get skins for mediawiki - is the haskell.org look available in this form? - [[User:MikeDodds|MikeDodds]] 12:33, 1 March 2006 (UTC)<br />
<br />
:I suppose I should publish the skin file somehow. I'm not sure the best way. &mdash;[[User:Ashley Y|Ashley Y]] 09:44, 25 March 2006 (UTC)<br />
<br />
:OK, see [[HaskellWiki:Site software]]. &mdash;[[User:Ashley Y|Ashley Y]] 01:15, 20 September 2006 (UTC)<br />
<br />
== [[Libraries and tools]] copyright status ==<br />
<br />
Dear Ashley Y,<br />
<br />
I saw that the page [[Libraries and tools/Genetic programming]] got a <nowiki>{{unknown copyright}}</nowiki> mark in the recent days during the moving to its own separate page. This mark asks me to resolve the copyright status.<br />
<br />
It was me who wrote the content of this page ([http://www.haskell.org/haskellwiki/?title=Libraries_and_tools&diff=2265&oldid=2252 here is the diff page showing this]) in February, so I thought it need not be licenced explicitly, it is automatically licenced under [[HaskellWiki:Licensing]].<br />
<br />
Have I to do something?<br />
<br />
Tank You very much in advance<br />
<br />
Best wishes<br />
<br />
[[User:EndreyMark|EndreyMark]] 12:32, 24 March 2006 (UTC)<br />
<br />
:Great, go ahead and remove the "unknown copyright" label. &mdash;[[User:Ashley Y|Ashley Y]] 09:42, 25 March 2006 (UTC)<br />
<br />
:Thank You, I have done it. [[User:EndreyMark|EndreyMark]] 18:05, 25 March 2006 (UTC)<br />
<br />
== Deletion of [[Continuation passing style]] ==<br />
<br />
Dear Ashley,<br />
<br />
Acidentally, I have created a [[Continuation passing style]] page superfluously.<br />
Because a [[Continuation]] article exists already, I suppose the superfluous empty page should be deleted, because its existence can be confusing (e.g. editors linking word "[[Continuation passing style]]" will not get a warning red link any more, but a misleading empty page). I cannot delete the page (only empty it, but it is not enough).<br />
<br />
Thank You in advance<br />
<br />
[[User:EndreyMark|EndreyMark]] 08:14, 27 October 2006 (UTC)<br />
<br />
:I made it a redirect instead. &mdash;[[User:Ashley Y|Ashley Y]] 18:44, 31 October 2006 (UTC)<br />
<br />
== Interwiki map ==<br />
<br />
Hi: could you add some stuff to the interwiki map? In [[Haste]], I was trying to interwiki to the English Wikipedia using the usual <nowiki>[[wikipedia:Scintilla]]</nowiki> interwiki link, but it didn't work (nor did en:, or wiki: - which just took one to c2.com). [[User:Gwern|Gwern]]<br />
<br />
== Same logo, less bytes ==<br />
<br />
If you're interested in using it, I shaved 407 bytes off the logo in the upper-left-hand corner of the wiki. It's [[:Image:Haskellwiki_logo_small.png|uploaded here]]. [[User:Olathe|Olathe]] 00:33, 12 August 2008 (UTC)<br />
<br />
== Latex upgrade ==<br />
While testing Pandoc's conversion of LaTeX to MediaWiki markup, I noticed some bugs. Compare [[User:Gwern/kenn]] to [https://secure.wikimedia.org/wikipedia/en/wiki/User:Gwern/kenn https://secure.wikimedia.org/wikipedia/en/wiki/User:Gwern/kenn]. The haskell.org version features many ugly red sections like '<nowiki>Failed to parse (unknown function\begin): \begin{array}{rclcl} \phi & ::= & P(t_1, \cdots, t_n) \\ & \mid & \neg\phi \\ & \mid & \phi_1 \Rightarrow \phi_2 \\ & \mid & TT & \mid & FF \\ & \mid & \phi_1 \wedge \phi_2 & \mid & \phi_1 \vee \phi_2 \\ & \mid & \forall x.\, \phi & \mid & \exists x.\, \phi \end{array}</nowiki>'.<br />
<br />
John MacFarlane, Pandoc's author, thinks this is because of outdated addons to MediaWiki or MediaWiki itself; this is consistent with the same source text not producing those errors on the English Wikipedia. Could you fix this? --[[User:Gwern|Gwern]] 10:46, 6 September 2008 (UTC)<br />
<br />
== Request for MediaWiki Upgrade ==<br />
I request that you update the MediaWiki software to a more recent version. Thanks in advance. &mdash;[[User:HowardBGolden|HowardBGolden]] 08:17, 4 October 2008 (UTC)<br />
<br />
:This will require a larger update to the machine that runs HaskellWiki, which I can't do easily. &mdash;[[User:Ashley Y|Ashley Y]] 07:56, 18 August 2009 (UTC)<br />
<br />
== Spam ==<br />
An indef block of http://www.haskell.org/haskellwiki/?title=Special:Contributions&target=D0rk23 please. --[[User:Gwern|Gwern]] 12:22, 7 July 2009 (UTC)<br />
<br />
:Done. &mdash;[[User:Ashley Y|Ashley Y]] 22:16, 6 August 2009 (UTC)<br />
<br />
----<br />
<br />
Block of http://www.haskell.org/haskellwiki/?title=Special:Contributions&target=HelenGarcia please. --[[User:Gwern|Gwern]] 01:09, 9 April 2010 (UTC)<br />
<br />
:And [[User:Carolin]]. --[[User:Gwern|Gwern]] 01:12, 9 April 2010 (UTC)<br />
<br />
== Sitenotice ==<br />
[[MediaWiki:Sitenotice]] needs editing badly; I have seen many people assume that no accounts are being created. Any change in wording would be better - how about 'To request an account, click here'? --[[User:Gwern|Gwern]] 13:36, 6 August 2009 (UTC)<br />
<br />
:Is this better? &mdash;[[User:Ashley Y|Ashley Y]] 22:14, 6 August 2009 (UTC)<br />
<br />
::Yes, loads. --[[User:Gwern|Gwern]] 01:09, 7 August 2009 (UTC)<br />
<br />
== Spam & account registration ==<br />
<br />
It has been a while since the spam became a real issue and account registration was disabled. Creating accounts has proven kind of draining for me, even when I pushed byorgey up to be listed first. Is there any chance we could re-enable registration and see whether the spammers have given up? We are surely driving away potential contributors with such a laborious sign-up procedure. --[[User:Gwern|Gwern]] 00:38, 27 February 2010 (UTC)<br />
<br />
:OK, I've opened it up again. Hopefully we'll be OK. &mdash;[[User:Ashley Y|Ashley Y]] 02:38, 16 March 2010 (UTC)<br />
<br />
::Well, we were pretty fine for the last couple months, but then a few dozen/hundred spam accounts got registered...<br />
::It seems to me we need an active admin. I nominate myself. The discussion on -cafe about new admins [http://www.mail-archive.com/haskell-cafe@haskell.org/msg60954.html petered out] last time (Peterson never replied to me), but now it's a little more urgent. --[[User:Gwern|Gwern]] 01:21, 12 July 2010 (UTC)<br />
<br />
:::We're in the process of moving to a new server running Debian and MediaWiki 1.12. &mdash;[[User:Ashley Y|Ashley Y]] 01:44, 12 July 2010 (UTC)<br />
<br />
::::Which will no doubt help. But spammers won't block themselves. --[[User:Gwern|Gwern]] 03:43, 12 July 2010 (UTC)<br />
<br />
:::::I think MediaWiki 1.12 has some extensions that will help. &mdash;[[User:Ashley Y|Ashley Y]] 03:58, 12 July 2010 (UTC)<br />
<br />
:What's the process for approving people to be admin? Should I ping the Cafe list about it? &mdash;[[User:Ashley Y|Ashley Y]] 17:36, 12 July 2010 (UTC)<br />
<br />
::I don't think there is any process. I linked an email in which I suggested several people for adminship (including myself), and no one objected to any of my choices, which is pretty much how the English Wikipedia did things in the early days. --[[User:Gwern|Gwern]] 00:27, 13 July 2010 (UTC)<br />
<br />
=== Steady spam ===<br />
<br />
Any chance we could turn on email autoconfirmation? That was recently switched on for the LessWrong wiki, which was suffering from a similar level of spam by apparently the same exact spammers (down to usernames and page content, sometimes), and has worked wonders. --[[User:Gwern|Gwern]] 17:17, 14 December 2011 (UTC)<br />
<br />
:I'll have a look over the weekend. I'm not sure if I have root access to the box, but I'll see what I can do. &mdash;[[User:Ashley Y|Ashley Y]] 02:47, 26 January 2012 (UTC)<br />
<br />
:OK, I switched on $wgEmailConfirmToEdit. &mdash;[[User:Ashley Y|Ashley Y]] 01:55, 30 January 2012 (UTC)<br />
<br />
::Thanks. Hasn't made too dramatic a dent, but it's early days yet. --[[User:Gwern|Gwern]] 00:04, 2 February 2012 (UTC)<br />
<br />
== Error in Hawiki.php ==<br />
<br />
I'm not sure if this is really causing any issues, but it's kind of alarming: If you look closely, you'll see that (under the hawiki skin) all the pages include essentially this HTML in teh <code>head</code>:<br />
<pre-html><br />
<script type="text/javascript" src="/haskellwiki/index.php?title=-&amp;action=raw&amp;smaxage=0&amp;gen=js&amp;useskin=hawiki"><br />
&lt;!-- site js --><br />
</script><br />
</pre-html><br />
<br />
Unfortunately, what comes back from MediaWiki when the browser asks for http://haskell.org/haskellwiki/index.php?title=-&action=raw&smaxage=0&gen=js&useskin=hawiki is not JavasSript, but instead this:<br />
<pre-html style="white-space: pre-wrap"><br />
<br /><br />
<b>Catchable fatal error</b>: Argument 1 passed to SkinHawiki::initPage() must be an instance of OutputPage, instance of StubObject given, called in /usr/share/mediawiki/includes/RawPage.php on line 165 and defined in <b>/srv/web/wikidata/skin/Hawiki.php</b> on line <b>23</b><br /><br />
</pre><br />
<br />
Similarly, there is a piece of CSS like this:<br />
<pre-css><br />
@import "/haskellwiki/index.php?title=-&action=raw&gen=css&maxage=18000&smaxage=0&useskin=hawiki";<br />
</pre-css><br />
and the same error occurs when the browser asks for http://haskell.org/haskellwiki/index.php?title=-&action=raw&gen=css&maxage=18000&smaxage=0&useskin=hawiki.<br />
<br />
P.S. It's also kind of annoying that most of the custom CSS is in wikistatic ([http://haskell.org/wikistatic/skins//hawiki/main.css hawiki/main.css]), rather than in [[MediaWiki:Common.css]] and [[MediaWiki:Hawiki.css]]. Though, now that I look really closely, I do see that [[MediaWiki:Common.css|Common.css]] not only exists, but even contains a few rules, which is nice!<br />
<br />
P.P.S. It's too bad we don't have the MediaWiki feature whereby users get to extend the skins by putting CSS/JS in subpages of their userpage...<br />
<br />
--[[User:SamB|SamB]] 05:45, 8 June 2011 (UTC)<br />
<br />
== I broke &lt;hask&gt; tags ==<br />
<br />
I'm guessing from your signature on [[HaskellWiki:Syntax_highlighting]] that you are the person to tell about this. See [[User:benmachine]]: it seems that leaving a comment tag unclosed inside a &lt;hask&gt; breaks syntax highlighting forever.<br />
--[[User:Benmachine|benmachine]] 19:31, 9 June 2011 (UTC)<br />
<br />
== operators look like comments in syntax highlighting ==<br />
<br />
Ashley,<br />
<br />
[[User talk:Henk-Jan van Tuyl|Henk-Jan van Tuyl]] and [[User talk:Jalexanderdatkins|myself]] have been discussing a teeny tiny issue with the syntax highlighter, which is that a user-defined operator beginning with the characters -- incorrectly causes the rest of the line to be formatted as a comment. This is immaterial everywhere except in the one example which is written on the wiki to show that it is not in fact a comment, which can be found at [[Keywords#--]]. What I have done there is to insert a zero-width space (a unicode character) between the two hyphens, but Henk-Jan van Tuyl reports that the zero-width space appears as a rectangle with his combination of browser/operating system. If you view an old version of the page (before my edit) you will see what the syntax highlighter was doing before that.<br />
<br />
Could the syntax highlighter be modified so that user-defined operators beginning with -- are not treated as one-line comments, or is it not worth it? (I suppose I could take that last line out and put it in a &lt;pre&gt; or something.) It just bothers me that the syntax highlighter appears to be contradicting the very point that the example is trying to make.<br />
<br />
Yours,<br />
<br />
[[User:Jalexanderdatkins|jalexanderdatkins]] 23:37, 5 August 2012 (UTC)</div>Jalexanderdatkinshttps://wiki.haskell.org/User_talk:Henk-Jan_van_TuylUser talk:Henk-Jan van Tuyl2012-08-05T23:26:35Z<p>Jalexanderdatkins: /* zero-width space in Keywords */ new section</p>
<hr />
<div>Hi,<br />
<br />
Of course you can move the page to something like:<br />
<br />
http://www.haskell.org/haskellwiki/Ro/Haskell/DSL<br />
<br />
Feel free to do it.<br />
<br />
Sincerely yours,<br />
<br />
:)<br />
<br />
== zero-width space in [[Keywords#--|Keywords]] ==<br />
<br />
Ah. We need to poke [[User:Ashley Y|Ashley Y]], who made the syntax highlighting stuff. Will do so now. [[User:Jalexanderdatkins|jalexanderdatkins]] 23:26, 5 August 2012 (UTC)</div>Jalexanderdatkinshttps://wiki.haskell.org/User_talk:JalexanderdatkinsUser talk:Jalexanderdatkins2012-08-05T23:18:03Z<p>Jalexanderdatkins: </p>
<hr />
<div>You have inserted zero-width space at page [[Keywords#--|Keywords]]; this character appears as a rectangle in my browser, most likely because this character is not defined the font I am using (I am using a very large font file). Can you find another solution?<br />
[[User:Henk-Jan van Tuyl|Henk-Jan van Tuyl]] 22:18, 5 August 2012 (UTC)</div>Jalexanderdatkinshttps://wiki.haskell.org/User_talk:JalexanderdatkinsUser talk:Jalexanderdatkins2012-08-05T23:17:17Z<p>Jalexanderdatkins: </p>
<hr />
<div>You have inserted zero-width space at page [[Keywords]]; this character appears as a rectangle in my browser, most likely because this character is not defined the font I am using (I am using a very large font file). Can you find another solution?<br />
[[User:Henk-Jan van Tuyl|Henk-Jan van Tuyl]] 22:18, 5 August 2012 (UTC)</div>Jalexanderdatkinshttps://wiki.haskell.org/KeywordsKeywords2012-08-04T16:08:28Z<p>Jalexanderdatkins: /* -- */ inserted zero-width space as formatting hack</p>
<hr />
<div>This page lists all Haskell keywords, feel free to edit. [[Hoogle]] searches will return results from this page. Please respect the Anchor macros.<br />
<br />
For additional information you might want to look at [http://www.haskell.org/onlinereport/ the Haskell 98 report].<br />
<br />
== ! ==<br />
<br />
Whenever a data [[constructor]] is applied, each argument to the<br />
constructor is evaluated if and only if the corresponding type in the<br />
algebraic data[[type]] declaration has a strictness flag, denoted by an<br />
exclamation point. For example:<br />
<br />
<haskell><br />
data STList a <br />
= STCons a !(STList a) -- the second argument to STCons will be <br />
-- evaluated before STCons is applied<br />
| STNil<br />
</haskell><br />
<br />
to illustrate the difference between strict versus lazy constructor<br />
application, consider the following:<br />
<br />
<haskell><br />
stList = STCons 1 undefined<br />
lzList = (:) 1 undefined<br />
stHead (STCons h _) = h -- this evaluates to undefined when applied to stList<br />
lzHead (h : _) = h -- this evaluates to 1 when applied to lzList<br />
</haskell><br />
<br />
! is also used in the [http://www.haskell.org/ghc/docs/latest/html/users_guide/bang-patterns.html "bang patterns"] (GHC extension), to indicate<br />
strictness in patterns:<br />
<br />
<haskell><br />
f !x !y = x + y<br />
</haskell><br />
<br />
== ' ==<br />
* Character literal: <hask>'a'</hask><br />
* [[Template Haskell]]: Name of a (value) variable or data constructor: <hask>'length</hask>, <hask>'Left</hask><br />
<br />
== <nowiki>''</nowiki> ==<br />
* [[Template Haskell]]: Name of a type constructor or class: <hask>''Int</hask>, <hask>''Either</hask>, <hask>''Show</hask><br />
<br />
== - ==<br />
This operator token is magic/irregular in the sense that<br />
<haskell>(- 1)</haskell><br />
is parsed as the negative integer -1, rather than as an operator [[section]], as it would be for any other operator:<br />
<haskell>(* 1) :: Num a => a -> a</haskell><br />
<haskell>(++ "foo") :: String -> String</haskell><br />
<br />
It is syntactic sugar for the <hask>negate</hask> function in Prelude. See [[unary operator]].<br />
If you want the section, you can use the <hask>subtract</hask> function or <hask>(+(-1))</hask>.<br />
<br />
== -- ==<br />
<br />
Starts a single-line comment, unless immediately followed by an operator character other than <hask>-</hask>:<br />
<br />
<haskell><br />
main = print "hello world" -- this is a comment<br />
--this is a comment as well<br />
---this too<br />
foobar --+ this_is_the_second_argument_of_the_dash_dash_plus_operator<br />
</haskell><br />
<br />
The multi-line variant for comments is <hask>{- comment -}</hask>.<br />
<br />
== -< ==<br />
[[Arrow notation]]<br />
<br />
== -<< ==<br />
[[Arrow notation]]<br />
<br />
<br />
== -> ==<br />
<br />
* The function type constructor:<br />
<haskell><br />
length :: [a] -> Int<br />
</haskell><br />
<br />
* In lambda functions:<br />
<haskell><br />
\x -> x + 1<br />
</haskell><br />
<br />
* To denote alternatives in case statements:<br />
<haskell><br />
case Just 3 of<br />
Nothing -> False<br />
Just x -> True<br />
</haskell><br />
<br />
* On the kind level (GHC specific):<br />
<haskell><br />
ghci> :kind (->)<br />
(->) :: ?? -> ? -> *<br />
</haskell><br />
<br />
* [[Functional dependencies]]<br />
<haskell><br />
-- This examples assumes that each type 'c' can "contain" only one type<br />
-- i.e. type 'c' uniquely determines type 'elt'<br />
class Contains c elt | c -> elt where<br />
...<br />
</haskell><br />
<br />
* [[View patterns]]<br />
<br />
== :: ==<br />
<br />
Read as "has type":<br />
<br />
<haskell><br />
length :: [a] -> Int<br />
</haskell><br />
<br />
"Length has type list-of-'a' to Int"<br />
<br />
Or "has kind" (GHC specific):<br />
<br />
<haskell><br />
Either :: * -> * -> *<br />
</haskell><br />
<br />
== ; ==<br />
* Statement separator in an explicit block (see [[layout]])<br />
<br />
== <- ==<br />
<br />
* In do-notation, "draw from":<br />
<haskell><br />
do x <- getChar<br />
putChar x<br />
</haskell><br />
<br />
* In list comprehension generators, "is drawn from":<br />
<haskell><br />
[ (x,y) | x <- [1..10], y <- ['a'..'z'] ]<br />
</haskell><br />
<br />
* In [[pattern guard]]s, "matches":<br />
<haskell><br />
f x y | Just z <- g x = True<br />
| otherwise = False<br />
</haskell><br />
<br />
== = ==<br />
Used in definitions.<br />
<br />
<haskell><br />
x = 4<br />
</haskell><br />
<br />
== => ==<br />
<br />
Used to indicate instance contexts, for example:<br />
<br />
<haskell><br />
sort :: Ord a => [a] -> [a]<br />
</haskell><br />
<br />
== > ==<br />
<br />
In a Bird's style [[Literate_programming|Literate Haskell file]], the > character is used to introduce a code line.<br />
<br />
<haskell><br />
comment line<br />
<br />
> main = print "hello world"<br />
</haskell><br />
<br />
== ? ==<br />
<br />
* [[Implicit parameters]]<br />
<br />
<haskell><br />
ghci> :t ?foo ++ "bar"<br />
?foo ++ "bar" :: (?foo::[Char]) => [Char]<br />
</haskell><br />
<br />
* On the [[kind]] level: The union of <hask>??</hask> and <hask>(#)</hask> (GHC-specific) <br />
<br />
<haskell><br />
ghci> :kind (->)<br />
(->) :: ?? -> ? -> *<br />
</haskell><br />
<br />
== ?? ==<br />
<br />
* Is an ordinary operator name on the value level and on the type level<br />
<br />
* On the [[kind]] level: The union of <hask>*</hask> and <hask>#</hask> (GHC-specific) <br />
<br />
<haskell><br />
ghci> :kind (->)<br />
(->) :: ?? -> ? -> *<br />
</haskell><br />
<br />
== # ==<br />
<br />
* [http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#magic-hash MagicHash]<br />
<br />
* On the [[kind]] level: The kind of [[unboxed]] types (GHC-specific) <br />
<br />
<haskell><br />
ghci> :m +GHC.Prim<br />
ghci> :set -XMagicHash<br />
ghci> :kind Int#<br />
Int# :: #<br />
</haskell><br />
<br />
== (#) ==<br />
<br />
* On the [[kind]] level: The kind of [[unboxed]] tuples (GHC-specific) <br />
<br />
<haskell><br />
ghci> :set -XMagicHash -XUnboxedTuples<br />
ghci> ghci> :k (# Char,Int #)<br />
(# Char,Int #) :: (#)<br />
</haskell><br />
<br />
== * ==<br />
<br />
* Is an ordinary operator name on the value level<br />
<br />
* On the [[kind]] level: The kind of boxed types (GHC-specific) <br />
<br />
<haskell><br />
ghci> :kind Int<br />
Int :: *<br />
</haskell><br />
<br />
== @ ==<br />
<br />
Patterns of the form var@pat are called as-patterns, and allow one to<br />
use var as a name for the value being matched by pat. For example:<br />
<haskell><br />
case e of { xs@(x:rest) -> if x==0 then rest else xs }<br />
</haskell><br />
<br />
is equivalent to:<br />
<br />
<haskell><br />
let { xs = e } in<br />
case xs of { (x:rest) -> if x==0 then rest else xs }<br />
</haskell><br />
<br />
== [|, |] ==<br />
* [[Template Haskell]]<br />
** Expression quotation: <hask> [| print 1 |] </hask><br />
** Declaration quotation: <hask> [d| main = print 1 |] </hask><br />
** Type quotation: <hask> [t| Either Int () |] </hask> <br />
** Pattern quotation: <hask> [p| (x,y) |] </hask><br />
** [[Quasiquotation]]: <hask> [nameOfQuasiQuoter| ... |] </hask><br />
<br />
== \ ==<br />
The backslash "\" is used<br />
<br />
* in multiline strings<br />
<haskell><br />
"foo\<br />
\bar"<br />
</haskell><br />
<br />
* in lambda functions<br />
<haskell><br />
\x -> x + 1<br />
</haskell><br />
<br />
<br />
== _ ==<br />
<br />
Patterns of the form _ are wildcards and are useful when some part of a<br />
pattern is not referenced on the right-hand-side. It is as if an<br />
identifier not used elsewhere were put in its place. For example,<br />
<br />
<haskell><br />
case e of { [x,_,_] -> if x==0 then True else False }<br />
</haskell><br />
<br />
is equivalent to:<br />
<br />
<haskell><br />
case e of { [x,y,z] -> if x==0 then True else False }<br />
</haskell><br />
<br />
<br />
<br />
<br />
<br />
== ` ==<br />
<br />
A function enclosed in back ticks "`" can be used as an infix operator.<br />
<br />
<haskell>2 `subtract` 10</haskell><br />
is the same as<br />
<haskell>subtract 2 10</haskell><br />
<br />
== {, } ==<br />
* Explicit block (disable [[layout]]), possibly with ";" .<br />
<br />
* Record update notation<br />
<haskell><br />
changePrice :: Thing -> Price -> Thing<br />
changePrice x new = x { price = new }<br />
</haskell><br />
<br />
* Comments (see below)<br />
<br />
== {-, -} ==<br />
<br />
Everything between "{-" followed by a space and "-}" is a block comment.<br />
<br />
<haskell><br />
{-<br />
hello<br />
world<br />
-}<br />
</haskell><br />
<br />
== | ==<br />
<br />
The "pipe" is used in several places<br />
<br />
* Data type definitions, "or"<br />
<haskell><br />
data Maybe a = Just a | Nothing<br />
</haskell><br />
<br />
* List comprehensions, "where"<br />
<haskell><br />
squares = [a*a | a <- [1..]]<br />
</haskell><br />
<br />
* Guards, "when"<br />
<haskell><br />
safeTail x | null x = []<br />
| otherwise = tail x<br />
</haskell><br />
<br />
* [[Functional dependencies]], "where"<br />
<haskell><br />
class Contains c elt | c -> elt where<br />
...<br />
</haskell><br />
<br />
== ~ ==<br />
<br />
* Lazy pattern bindings. Matching the pattern ~pat against a value always<br />
suceeds, and matching will only diverge when one of the variables bound<br />
in the pattern is used.<br />
<br />
<haskell><br />
f1, f2 :: Maybe Int -> String<br />
f1 x = case x of <br />
Just n -> "Got it"<br />
f2 x = case x of<br />
~(Just n) -> "Got it"<br />
<br />
(+++), (++++) :: (a -> b) -> (c -> d) -> (a, c) -> (b, d) <br />
(f +++ g) ~(x, y) = (f x, g y)<br />
(f ++++ g) (x, y) = (f x, g y)<br />
</haskell><br />
<br />
Then we have:<br />
<br />
<haskell><br />
f1 Nothing<br />
Exception: Non-exhaustive patterns in case<br />
<br />
f2 Nothing<br />
"Got it"<br />
<br />
(const 1 +++ const 2) undefined<br />
(1,2)<br />
<br />
(const 1 ++++ const 2) undefined<br />
Exception: Prelude.undefined<br />
</haskell><br />
<br />
For more details see [http://en.wikibooks.org/wiki/Haskell/Laziness#Lazy_pattern_matching the Haskell Wikibook].<br />
<br />
* Equality constraints. Assert that two types in a context must be the same:<br />
<br />
<haskell><br />
example :: F a ~ b => a -> b<br />
</haskell><br />
<br />
Here the type "F a" must be the same as the type "b", which allows one to constrain polymorphism (especially where type families are involved), but to a lesser extent than functional dependencies. See [[Type_families#Equality_constraints|Type Families]].<br />
<br />
== as ==<br />
<br />
Renaming module imports. Like <hask>qualified</hask> and <hask>hiding</hask>, <hask>as</hask> is not a reserved word but may be used as function or variable name.<br />
<br />
<haskell><br />
import qualified Data.Map as M<br />
<br />
main = print (M.empty :: M.Map Int ())<br />
</haskell><br />
<br />
== <span id="case">case</span>, <span id="of">of</span> ==<br />
<br />
A case expression has the general form<br />
<br />
<haskell><br />
case e of { p1 match1 ; ... ; pn matchn }<br />
</haskell><br />
<br />
where each <code>match</code><sub>i</sub> is of the general form<br />
<br />
<haskell><br />
| g1 -> e1<br />
...<br />
| gm -> em<br />
where decls<br />
</haskell><br />
<br />
Each alternative consists of patterns <code>p</code><sub>i</sub> and their matches, <code>match</code><sub>i</sub>. Each<br />
<code>match</code><sub>i</sub> in turn consists of a sequence of pairs of guards <code>g</code><sub>ij</sub> and bodies <code>e</code><sub>ij</sub><br />
(expressions), followed by optional bindings (<code>decls</code><sub>i</sub>) that scope over all<br />
of the guards and expressions of the alternative. An alternative of the<br />
form<br />
<br />
<haskell><br />
pat -> exp where decls<br />
</haskell><br />
<br />
is treated as shorthand for:<br />
<br />
<haskell><br />
pat | True -> exp<br />
where decls<br />
</haskell><br />
<br />
A case expression must have at least one alternative and each<br />
alternative must have at least one body. Each body must have the same<br />
type, and the type of the whole expression is that type.<br />
<br />
A case expression is evaluated by pattern matching the expression <code>e</code><br />
against the individual alternatives. The alternatives are tried<br />
sequentially, from top to bottom. If <code>e</code> matches the pattern in the<br />
alternative, the guards for that alternative are tried sequentially from<br />
top to bottom, in the environment of the case expression extended first<br />
by the bindings created during the matching of the pattern, and then by<br />
the <code>decls</code><sub>i</sub>&nbsp; in the <code>where</code> clause associated with that alternative. If one<br />
of the guards evaluates to <code>True</code>, the corresponding right-hand side is<br />
evaluated in the same environment as the guard. If all the guards<br />
evaluate to <code>False</code>, matching continues with the next alternative. If no<br />
match succeeds, the result is _|_.<br />
<br />
== class ==<br />
<br />
A [http://haskell.org/onlinereport/decls.html#class-decls class declaration] <br />
introduces a new type class and the overloaded operations that must be<br />
supported by any type that is an instance of that class.<br />
<haskell><br />
class Num a where<br />
(+) :: a -> a -> a<br />
negate :: a -> a<br />
</haskell><br />
<br />
== data ==<br />
<br />
The [http://haskell.org/onlinereport/decls.html#user-defined-datatypes data] <br />
declaration is how one introduces new algebraic data [[type]]s into<br />
Haskell. For example:<br />
<br />
<haskell><br />
data Set a = NilSet <br />
| ConsSet a (Set a)<br />
</haskell><br />
<br />
Another example, to create a datatype to hold an [[Abstract_syntax_tree|abstract syntax tree]] for an expression, one could use:<br />
<br />
<haskell><br />
data Exp = Ebin Operator Exp Exp <br />
| Eunary Operator Exp <br />
| Efun FunctionIdentifier [Exp] <br />
| Eid SimpleIdentifier<br />
</haskell><br />
<br />
where the [[type]]s <code>Operator, FunctionIdentifier</code> and <code>SimpleIdentifier</code> are defined elsewhere. <br />
<br />
See the page on [[type]]s for more information, links and examples.<br />
<br />
== data family ==<br />
Declares a datatype family (see [[type families]]). GHC language extension.<br />
<br />
== data instance ==<br />
Declares a datatype family instance (see [[type families]]). GHC language extension.<br />
<br />
<br />
== default ==<br />
<br />
Ambiguities in the class Num are most common, so Haskell provides<br />
a way to resolve them---with a default declaration:<br />
<br />
<haskell><br />
default (Int)<br />
</haskell><br />
<br />
Only one default declaration is permitted per module, and its effect is<br />
limited to that module. If no default declaration is given in a module<br />
then it assumed to be:<br />
<br />
<haskell><br />
default (Integer, Double)<br />
</haskell><br />
<br />
== deriving ==<br />
<br />
data and newtype declarations contain an optional deriving form. If the<br />
form is included, then derived instance declarations are automatically<br />
generated for the datatype in each of the named classes.<br />
<br />
[http://haskell.org/onlinereport/decls.html#derived-decls Derived instances] provide convenient commonly-used operations for user-defined<br />
datatypes. For example, derived instances for datatypes in the class Eq<br />
define the operations == and /=, freeing the programmer from the need to<br />
define them.<br />
<br />
<haskell><br />
data T = A<br />
| B<br />
| C<br />
deriving (Eq, Ord, Show)<br />
</haskell><br />
<br />
In the case of newtypes, GHC extends this mechanism to [[Cunning Newtype Deriving]].<br />
<br />
== deriving instance ==<br />
<br />
Standalone deriving (GHC language extension).<br />
<br />
<haskell><br />
{-# LANGUAGE StandaloneDeriving #-}<br />
data A = A<br />
<br />
deriving instance Show A<br />
</haskell><br />
<br />
== do ==<br />
<br />
Syntactic sugar for use with monadic expressions. For example:<br />
<br />
<haskell><br />
do { x ; result <- y ; foo result }<br />
</haskell><br />
<br />
is shorthand for:<br />
<br />
<haskell><br />
x >> <br />
y >>= \result -><br />
foo result<br />
</haskell><br />
<br />
== forall ==<br />
<br />
This is a GHC/Hugs extension, and as such is not portable Haskell 98. <br />
It is only a reserved word within types. <br />
<br />
Type variables in a Haskell type expression are all assumed to be<br />
universally quantified; there is no explicit syntax for universal<br />
quantification, in standard Haskell 98. For example, the type expression<br />
<hask>a -> a</hask> denotes the type <hask>forall a. a ->a</hask>. <br />
For clarity, however, we often write quantification explicitly when<br />
discussing the types of Haskell programs. When we write an explicitly<br />
quantified type, the scope of the forall extends as far to the right as<br />
possible; for example, <br />
<haskell><br />
forall a. a -> a<br />
</haskell><br />
means <br />
<haskell><br />
forall a. (a -> a)<br />
</haskell><br />
<br />
GHC [http://www.haskell.org/ghc/docs/latest/html/users_guide/data-type-extensions.html#type-synonyms introduces] a <hask>forall</hask> keyword, allowing explicit quantification, for example, to encode <br />
[http://www.haskell.org/ghc/docs/latest/html/users_guide/data-type-extensions.html#existential-quantification existential types]: <br />
<haskell><br />
data Foo = forall a. MkFoo a (a -> Bool)<br />
| Nil<br />
<br />
MkFoo :: forall a. a -> (a -> Bool) -> Foo<br />
Nil :: Foo<br />
<br />
[MkFoo 3 even, MkFoo 'c' isUpper] :: [Foo]<br />
</haskell><br />
<br />
== foreign ==<br />
<br />
A keyword for the [[Foreign Function Interface]] (commonly called the FFI) that introduces either a <hask>foreign import</hask> declaration, which makes a function from a non-Haskell library available in a Haskell program, or a <hask>foreign export</hask> declaration, which allows a function from a Haskell module to be called in non-Haskell contexts.<br />
<br />
== hiding ==<br />
<br />
When importing modules, without introducing a name into scope, entities can be excluded by using the form<br />
<haskell><br />
hiding (import1 , ... , importn )<br />
</haskell><br />
which specifies that all entities exported by the named module should be<br />
imported except for those named in the list.<br />
<br />
For example:<br />
<haskell><br />
import Prelude hiding (lookup,filter,foldr,foldl,null,map)<br />
</haskell><br />
<br />
== <span id="if">if</span>, <span id="then">then</span>, <span id="else">else</span> ==<br />
<br />
A conditional expression has the form:<br />
<br />
<haskell><br />
if e1 then e2 else e3<br />
</haskell><br />
<br />
and returns the value of e2 if the value of e1 is True, e3 if e1 is False, and _|_ otherwise.<br />
<br />
<haskell><br />
max a b = if a > b then a else b<br />
</haskell><br />
<br />
== import ==<br />
<br />
[http://haskell.org/onlinereport/modules.html Modules] may reference<br />
other modules via explicit import declarations, each giving the name of<br />
a module to be imported and specifying its entities to be imported.<br />
<br />
For example:<br />
<haskell><br />
module Main where<br />
import A<br />
import B<br />
main = A.f >> B.f<br />
<br />
module A where<br />
f = ...<br />
<br />
module B where<br />
f = ...<br />
</haskell><br />
<br />
See also [[#as | as]], [[#hiding | hiding]] , [[#qualified | qualified]] and the page [[Import]]<br />
<br />
== <span id="infix">infix</span>, <span id="infixl">infixl</span>, <span id="infixr">infixr</span> ==<br />
<br />
A [http://haskell.org/onlinereport/decls.html fixity declaration] gives<br />
the fixity and binding precedence of one or more operators. The integer<br />
in a fixity declaration must be in the range 0 to 9. A fixity<br />
declaration may appear anywhere that a [[type signature]] appears and, like<br />
a type signature, declares a property of a particular operator.<br />
<br />
There are three kinds of fixity, non-, left- and right-associativity<br />
(infix, infixl, and infixr, respectively), and ten precedence levels, 0<br />
to 9 inclusive (level 0 binds least tightly, and level 9 binds most<br />
tightly).<br />
<br />
<haskell><br />
module Bar where<br />
infixr 7 `op`<br />
op = ...<br />
</haskell><br />
<br />
== instance ==<br />
<br />
An instance declaration declares that a type is an instance of a class<br />
and includes the definitions of the overloaded operations - called class<br />
methods - instantiated on the named type.<br />
<br />
<haskell><br />
instance Num Int where<br />
x + y = addInt x y<br />
negate x = negateInt x<br />
</haskell><br />
<br />
== <span id="let">let</span>, <span id="in">in</span> ==<br />
<br />
Let expressions have the general form:<br />
<br />
<haskell>let { d1 ; ... ; dn } in e</haskell><br />
<br />
They introduce a nested, lexically-scoped, mutually-recursive list of declarations (let is often called letrec in other languages). The scope of the declarations is the expression e and the right hand side of the declarations.<br />
<br />
Within <hask>do</hask>-blocks or list comprehensions <hask>let { d1 ; ... ; dn }</hask> without <hask>in</hask> serves to indroduce local bindings.<br />
<br />
== [http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#id3017137 mdo] ==<br />
<br />
The recursive <hask>do</hask> keyword enabled by -fglasgow-exts<br />
<br />
== module ==<br />
<br />
Taken from: [http://www.haskell.org/tutorial/modules.html A Gentle Introduction to Haskell, Version 98]<br />
<br />
Technically speaking, a module is really just one big declaration which begins with the keyword module; here's an example for a module whose name is Tree:<br />
<br />
<haskell><br />
module Tree ( Tree(Leaf,Branch), fringe ) where<br />
<br />
data Tree a = Leaf a | Branch (Tree a) (Tree a) <br />
<br />
fringe :: Tree a -> [a]<br />
fringe (Leaf x) = [x]<br />
fringe (Branch left right) = fringe left ++ fringe right<br />
</haskell><br />
<br />
== newtype ==<br />
<br />
The <code>newtype</code> declaration is how one introduces a renaming for an algebraic data [[type]] into Haskell. This is different from <code>type</code> below, as a <code>newtype</code> requires a new [[constructor]] as well. As an example, when writing a compiler<br />
one sometimes further qualifies <code>Identifier</code>s to assist in type safety checks:<br />
<br />
newtype SimpleIdentifier = SimpleIdentifier Identifier<br />
newtype FunctionIdentifier = FunctionIdentifier Identifier<br />
<br />
Most often, one supplies [[smart constructors]] and [[destructor]]s for these to ease working with them.<br />
<br />
See the page on [[type]]s for more information, links and examples.<br />
<br />
For the differences between <code>newtype</code> and <code>data</code>, see [[Newtype]].<br />
<br />
== proc ==<br />
proc (arrow abstraction)<br />
is a kind of lambda, except that it constructs an arrow instead of a function.<br />
<br />
[[Arrow notation]]<br />
<br />
== qualified ==<br />
<br />
Used to import a module, but not introduce a name into scope. For example, Data.Map exports lookup, which would clash with the Prelude version of lookup, to fix this:<br />
<br />
<haskell><br />
import qualified Data.Map<br />
<br />
f x = lookup x -- use the Prelude version<br />
g x = Data.Map.lookup x -- use the Data.Map version<br />
</haskell><br />
<br />
Of course, Data.Map is a bit of a mouthful, so qualified also allows the use of as.<br />
<br />
<haskell><br />
import qualified Data.Map as M<br />
<br />
f x = lookup x -- use Prelude version<br />
g x = M.lookup x -- use Data.Map version<br />
</haskell><br />
<br />
== rec ==<br />
The [http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#mdo-notation rec] keyword can be used when the <code>-XDoRec</code> flag is given; it allows recursive bindings in a do-block.<br />
<br />
<haskell><br />
{-# LANGUAGE DoRec #-}<br />
justOnes = do { rec { xs <- Just (1:xs) }<br />
; return (map negate xs) }<br />
</haskell><br />
<br />
== type ==<br />
<br />
The <code>type</code> declaration is how one introduces an alias for an algebraic data [[type]] into Haskell. As an example, when writing a compiler<br />
one often creates an alias for identifiers:<br />
<br />
<haskell><br />
type Identifier = String<br />
</haskell><br />
<br />
This allows you to use <code>Identifer</code> wherever you had used <code>String</code> and if something is of type <code>Identifier</code> it<br />
may be used wherever a <code>String</code> is expected.<br />
<br />
See the page on [[type]]s for more information, links and examples.<br />
<br />
Some common <code>type</code> declarations in the Prelude include:<br />
<br />
<haskell><br />
type FilePath = String<br />
type String = [Char]<br />
type Rational = Ratio Integer<br />
type ReadS a = String -> [(a,String)]<br />
type ShowS = String -> String<br />
</haskell><br />
<br />
== type family ==<br />
Declares a type synonym family (see [[type families]]). GHC language extension.<br />
<br />
== type instance ==<br />
Declares a type synonym family instance (see [[type families]]). GHC language extension.<br />
<br />
<br />
<br />
== where ==<br />
<br />
Used to introduce a module, instance, class or [[GADT]]:<br />
<haskell><br />
module Main where<br />
<br />
class Num a where<br />
...<br />
<br />
instance Num Int where<br />
...<br />
<br />
data Something a where<br />
...<br />
</haskell><br />
<br />
And to bind local variables:<br />
<haskell><br />
f x = y<br />
where y = x * 2<br />
<br />
g z | z > 2 = y<br />
where y = x * 2<br />
</haskell><br />
<br />
<br />
[[Category:Language]]</div>Jalexanderdatkinshttps://wiki.haskell.org/EditorsEditors2012-08-04T12:27:56Z<p>Jalexanderdatkins: Yi</p>
<hr />
<div>[[Category:Tools]]<br />
<br />
''For detailed information on Haskell IDEs, see [[IDEs]].''<br />
<br />
This page lists Haskell-aware editors with support for Haskell syntax highlighting and formatting support in text editors, grouped by platform.<br />
<br />
Multi-platform<br />
* [http://www.gnu.org/software/emacs/ Emacs]<br />
** [[Haskell mode for Emacs |Haskell mode]]<br />
** Integration with [[Hugs]]<br />
* [http://www.vim.org/ Vim]<br />
** [http://www.vim.org/scripts/script.php?script_id=2356 Superior Haskell Interaction Mode]<br />
* [http://www.nedit.org/ Nedit]<br />
* [http://www.jedsoft.org/jed/ Jed]<br />
* [http://www.geany.org/ Geany]<br />
* [http://www.sublimetext.com/ Sublime Text] (proprietary)<br />
* [http://www.activestate.com/komodo-edit Komodo Edit]<br />
* [[Yi]] (work in progress; no binaries yet)<br />
Linux<br />
* [http://kate-editor.org/kate Kate (KDE)]<br />
* [http://www.scintilla.org/SciTE.html SciTE] (Also see these [[Tips for using SciTE with Haskell|tips]])<br />
Windows<br />
* [http://www.textpad.com/ Textpad]<br />
* [http://notepad-plus.sourceforge.net Notepad++]<br />
MacOS X<br />
* [http://www.codingmonkeys.de/subethaedit/ SubEthaEdit]<br />
* [http://macromates.com/ TextMate] has a [http://macromates.com/textmate/manual/bundles#installing_a_bundle Haskell bundle]<br />
* [http://www.barebones.com/products/textwrangler/ TextWrangler] has a [http://boogus.wordpress.com/2010/05/13/syntax-highlighting-for-haskell-on-textwrangler/ Haskell extension]</div>Jalexanderdatkinshttps://wiki.haskell.org/EditorsEditors2012-08-04T12:23:17Z<p>Jalexanderdatkins: komodo edit</p>
<hr />
<div>[[Category:Tools]]<br />
<br />
''For detailed information on Haskell IDEs, see [[IDEs]].''<br />
<br />
This page lists Haskell-aware editors with support for Haskell syntax highlighting and formatting support in text editors, grouped by platform.<br />
<br />
Multi-platform<br />
* [http://www.gnu.org/software/emacs/ Emacs]<br />
** [[Haskell mode for Emacs |Haskell mode]]<br />
** Integration with [[Hugs]]<br />
* [http://www.vim.org/ Vim]<br />
** [http://www.vim.org/scripts/script.php?script_id=2356 Superior Haskell Interaction Mode]<br />
* [http://www.nedit.org/ Nedit]<br />
* [http://www.jedsoft.org/jed/ Jed]<br />
* [http://www.geany.org/ Geany]<br />
* [http://www.sublimetext.com/ Sublime Text] (proprietary)<br />
* [http://www.activestate.com/komodo-edit Komodo Edit]<br />
Linux<br />
* [http://kate-editor.org/kate Kate (KDE)]<br />
* [http://www.scintilla.org/SciTE.html SciTE] (Also see these [[Tips for using SciTE with Haskell|tips]])<br />
Windows<br />
* [http://www.textpad.com/ Textpad]<br />
* [http://notepad-plus.sourceforge.net Notepad++]<br />
MacOS X<br />
* [http://www.codingmonkeys.de/subethaedit/ SubEthaEdit]<br />
* [http://macromates.com/ TextMate] has a [http://macromates.com/textmate/manual/bundles#installing_a_bundle Haskell bundle]<br />
* [http://www.barebones.com/products/textwrangler/ TextWrangler] has a [http://boogus.wordpress.com/2010/05/13/syntax-highlighting-for-haskell-on-textwrangler/ Haskell extension]</div>Jalexanderdatkinshttps://wiki.haskell.org/TypeType2012-07-31T12:18:05Z<p>Jalexanderdatkins: /* Type and newtype */ Programming guidelines#Records</p>
<hr />
<div>In Haskell, '''types''' are how you describe the data your program will work with.<br />
<br />
[[Category:Language]]<br />
<br />
==Data declarations==<br />
<br />
One introduces, or declares, a type in Haskell via the <code>data</code> statement. In general a data declaration looks like:<br />
<br />
data [context =>] type tv1 ... tvi = con1 c1t1 c1t2... c1tn |<br />
... | conm cmt1 ... cmtq<br />
[deriving]<br />
<br />
which probably explains nothing if you don't already know Haskell!<br />
<br />
The essence of the above statement is that you use the keyword <hask>data</hask>,<br />
supply an optional context, give the type name and a variable number of <br />
[[type variable]]s. This is then followed by a variable number of [[constructor]]s, each of which has a list of [[type variable]]s or [[type constant]]s. At the end, there is an optional <code>deriving</code>.<br />
<br />
There are a number of other subtleties associated with this, such as requiring<br />
parameters to the data constructors to be [[eager]], what [[Type class|class]]es are<br />
allowed in the [[deriving]], use of [[field]] names in the constructors<br />
and what the [[context]] actually does. Please refer to the specific articles for more on each of those.<br />
<br />
Let's look at some examples. The Haskell standard data type [[Maybe]] is typically declared as:<br />
<haskell><br />
data Maybe a = Just a | Nothing<br />
</haskell><br />
What this means is that the type '''Maybe''' has one type variable, represented by the ''a'' and two [[constructor]]s '''Just''' and '''Nothing'''. (Note that Haskell requires type names and constructor names to begin with an uppercase letter). The '''Just''' constructor takes one parameter, of type ''a''.<br />
<br />
As another example, consider binary [[Tree]]s. They could be represented by:<br />
<haskell><br />
data Tree a = Branch (Tree a) (Tree a) | Leaf a<br />
</haskell><br />
Here, one of the constructors, '''Branch''' of '''Tree''' takes two trees as<br />
parameters to the constructor, while '''Leaf''' takes a value of type ''a''. This type of recursion is a very common [[:Category:Idioms |pattern]] in Haskell.<br />
<br />
==Type and newtype==<br />
<br />
The other two ways one may introduce types to Haskell programs are via the<br />
<hask>type</hask> and <hask>newtype</hask> statements.<br />
<br />
<hask>type</hask> introduces a synonym for a type and uses the same data<br />
constructors. <hask>newtype</hask> introduces a renaming of a type and <br />
requires you to provide new constructors.<br />
<br />
When using a <hask>type</hask> declaration, the type synonym and its base type<br />
are interchangeble almost everywhere (There are some restrictions when dealing with [[instance]] declarations). For example, if you had the declaration:<br />
<haskell><br />
type Name = String<br />
</haskell><br />
then any [[function]] you had declared that had <hask>String</hask> in its<br />
signature could be used on any element of type <code>Name</code><br />
<br />
However, if one had the declaration:<br />
<haskell> <br />
newtype FirstName = FirstName String<br />
</haskell><br />
this would no longer be the case. Functions would have to be declared that <br />
actually were defined on '''FirstName'''. Often, one creates a deconstructor<br />
at the same time which helps alleviate this requirement. e.g.:<br />
<haskell><br />
unFirstName :: FirstName -> String<br />
unFirstName (FirstName s) = s<br />
</haskell><br />
This is often done by the use of [[field|field labels]] in the <code>newtype</code>. (Note<br />
that many consider the Haskell field implementation sub-optimal, while <br />
others use it extensively. See [[Programming guidelines#Records|Programming guidelines]] and [[Future of Haskell]])<br />
<br />
==A simple example==<br />
<br />
Suppose you want to create a program to play bridge. You need something to represent cards. Here is one way to do that.<br />
<br />
First, create data types for the suit and card number.<br />
<haskell><br />
data Suit = Club | Diamond | Heart | Spade<br />
deriving (Read, Show, Enum, Eq, Ord)<br />
<br />
data CardValue = Two | Three | Four<br />
| Five | Six | Seven | Eight | Nine | Ten <br />
| Jack | Queen | King | Ace<br />
deriving (Read, Show, Enum, Eq, Ord)<br />
</haskell><br />
Each of these uses a [[deriving]] clause to allow us to convert them from / to [[String]] and Int, test them for equality and ordering. With types like this, <br />
where there are no [[type variable]]s, equality is based upon which constructor is used and order is determined by the order you wrote them, e.g. <code>Three</code> is less than <code>Queen</code>.<br />
<br />
Now we define an actual <code>Card</code><br />
<haskell> <br />
data Card = Card {value :: CardValue, <br />
suit :: Suit}<br />
deriving (Read, Show, Eq)<br />
</haskell><br />
In this definition, we use [[field]]s, which give us ready made functions to<br />
access the two parts of a <code>Card</code>. Again, [[type variables]] were not<br />
used, but the data [[constructor]] requires its two parameters to be of<br />
specific types, <code>CardValue</code> and <code>Suit</code>.<br />
<br />
The deriving clause here only specifies three of our desired [[Type class|classes]], we supply [[instance]] declarations for [[Ord]] and [[Enum]]:<br />
<haskell><br />
instance Ord Card where<br />
compare c1 c2 = compare (value c1, suit c1) (value c2, suit c2)<br />
<br />
instance Enum Card where<br />
toEnum n = let (v,s) = n`divMod`4 in Card (toEnum v) (toEnum s)<br />
fromEnum c = fromEnum (value c) * 4 + fromEnum (suit c)<br />
</haskell><br />
Finally, we alias the type <code>Deck</code> to a list of <code>Card</code>s<br />
and populate the deck with a [[list comprehension]] <br />
<haskell><br />
type Deck = [Card]<br />
<br />
deck::Deck<br />
deck = [Card val su | val <- [Two .. Ace], su <- [Club .. Spade]]<br />
</haskell><br />
<br />
==Please add==<br />
<br />
Further illustrative examples would be most appreciated.<br />
<br />
==See also==<br />
Read the articles about data [[constructor]]s and [[Type class|class]]es. As well the<br />
[http://haskell.org/definition/haskell98-report.pdf Haskell 98 report] and<br />
your chosen implementation (e.g. [[GHC/Documentation]]) have the latest words.<br />
<br />
*[[Determining the type of an expression]] - Let the Haskell compiler compute the type of expression<br />
*[[:Category:Language extensions | Language extensions]] - many language extensions are to do with changes to the type system.<br />
*[[Smart constructors]] shows some interesting examples including a non-trivial usage of <code>newtype</code>.<br />
*[[Unboxed type]] shows ways to have values closer to the bare metal :).<br />
*[[Phantom type]] discusses types without constructors.<br />
*[[Type witness]] gives an example of [[Generalised algebraic datatype | GADTs]], a [[GHC]] extension.<br />
*[[Existential type]] shows how to implement a common O-O programming paradigm.<br />
*[[Type arithmetic]] implements the [[Peano numbers]].<br />
*[[Reified type]], [[Non-trivial type synonyms]], [[Abstract data type]], [[Concrete data type]], [[Algebraic data type]].<br />
*[[Research_papers/Type_systems]] allow the curious to delve deeper.<br />
<br />
Languages: [[型|ja]]</div>Jalexanderdatkinshttps://wiki.haskell.org/Programming_guidelinesProgramming guidelines2012-07-31T12:02:03Z<p>Jalexanderdatkins: /* File Format */ "i.e" -> "e.g."</p>
<hr />
<div>Programming guidelines shall help to make the code of a project better<br />
readable and maintainable by the varying number of contributors.<br />
<br />
It takes some programming experience to develop something like a<br />
personal "coding style" and guidelines only serve as rough shape for<br />
code. Guidelines should be followed by all members working on the<br />
project even if they prefer (or are already used to) different<br />
guidelines.<br />
<br />
These guidelines have been originally set up for the hets-project<br />
[http://www.informatik.uni-bremen.de/cofi/hets/ hets-project] and are<br />
now put on the [http://haskell.org/haskellwiki/ HaskellWiki] gradually<br />
integrating parts of the old hawiki<br />
entries [http://haskell.org/haskellwiki/Things_to_avoid ThingsToAvoid] and<br />
HaskellStyle (hopefully not<br />
hurting someone's copyrights). The other related entry<br />
TipsAndTricks treats more<br />
specific points that are left out here,<br />
<br />
Surely some style choices are a bit arbitrary (or "religious") and<br />
too restrictive with respect to language extensions. Nevertheless I hope<br />
to keep up these guidelines (at least as a basis) for our project<br />
in order to avoid maintaining diverging guidelines. Of course I want<br />
to supply - partly tool-dependent - reasons for certain decisions and<br />
also show alternatives by possibly bad examples. At the time of<br />
writing I use ghc-6.4.1, haddock-0.7 and (GNU-) emacs with the latest<br />
[http://www.haskell.org/haskell-mode/ haskell mode].<br />
<br />
The following quote and links are taken from<br />
HaskellStyle:<br />
<br />
We all have our own ideas about good Haskell style. There's More Than<br />
One Way To Do It. But some ways are better than others.<br />
<br />
Some comments from the GHC team about their internal coding<br />
standards can be found at<br />
http://hackage.haskell.org/trac/ghc/wiki/WorkingConventions<br />
<br />
Also http://research.microsoft.com/~simonpj/papers/haskell-retrospective/<br />
contains some brief comments on syntax and style,<br />
<br />
What now follows are descriptions of program documentation, file<br />
format, naming conventions and good programming practice (adapted form<br />
Matt's C/C++ Programming Guidelines and the Linux kernel coding<br />
style).<br />
<br />
<br />
=== Documentation ===<br />
<br />
<br />
Comments are to be written in application terms (i.e. user's point of<br />
view). Don't use technical terms - that's what the code is for!<br />
<br />
Comments should be written using correct spelling and grammar in complete<br />
sentences with punctation (in English only).<br />
<br />
"Generally, you want your comments to tell WHAT your code does, not HOW.<br />
Also, try to avoid putting comments inside a function body: if the<br />
function is so complex that you need to separately comment parts of it,<br />
you should probably" (... decompose it)<br />
<br />
Put a haddock comment on top of every exported function and data type!<br />
Make sure haddock accepts these comments.<br />
<br />
<br />
=== File Format ===<br />
<br />
<br />
All Haskell source files start with a haddock header of the form:<br />
<br />
<pre><br />
{- |<br />
Module : <File name or $Header$ to be replaced automatically><br />
Description : <optional short text displayed on contents page><br />
Copyright : (c) <Authors or Affiliations><br />
License : <license><br />
<br />
Maintainer : <email><br />
Stability : unstable | experimental | provisional | stable | frozen<br />
Portability : portable | non-portable (<reason>)<br />
<br />
<module description starting at first column><br />
-}<br />
</pre><br />
<br />
A possible compiler pragma (like {-# LANGUAGE CPP #-}) may precede<br />
this header. The following hierarchical module name must of course<br />
match the file name.<br />
<br />
Make sure that the description is changed to meet the module (if the<br />
header was copied from elsewhere). Insert your email address as maintainer.<br />
<br />
Try to write portable (Haskell98) code. If you use e.g. multi-parameter<br />
type classes and functional dependencies the code becomes<br />
"non-portable (MPTC with FD)".<br />
<br />
The \$Header\$ entry will be automatically expanded.<br />
<br />
Lines should not be longer than 80 (preferably 75)<br />
characters to avoid wrapped lines (for casual readers)!<br />
<br />
Don't leave trailing white space in your code in every line.<br />
<br />
Expand all your tabs to spaces to avoid the danger of wrongly expanding<br />
them (or a different display of tabs versus eight spaces). Possibly put<br />
something like the following in your ~/.emacs file.<br />
<br />
(custom-set-variables '(indent-tabs-mode nil))<br />
<br />
The last character in your file should be a newline! Under solaris<br />
you'll get a warning if this is not the case and sometimes last lines<br />
without newlines are ignored (i.e. "#endif" without newline). Emacs<br />
usually asks for a final newline.<br />
<br />
You may use http://hackage.haskell.org/package/scan to check your file format.<br />
<br />
The whole module should not be too long (about 400 lines)<br />
<br />
=== Naming Conventions ===<br />
<br />
<br />
In Haskell types start with capital and functions with lowercase<br />
letters, so only avoid infix identifiers! Defining symbolic infix<br />
identifiers should be left to library writers only.<br />
<br />
(The infix identifier "\\" at the end of a line causes cpp preprocessor<br />
problems.)<br />
<br />
Names (especially global ones) should be descriptive and if you need<br />
long names write them as mixed case words (aka camelCase). (but "tmp"<br />
is to be preferred over "thisVariableIsATemporaryCounter")<br />
<br />
Also in the standard libraries, function names with multiple words are<br />
written using the camelCase convention. Similarly, type, typeclass and<br />
constructor names are written using the StudlyCaps convention.<br />
<br />
Some parts of our code use underlines (without unnecessary uppercase<br />
letters) for long identifiers to better reflect names given with<br />
hyphens in the requirement documentation. Also such names should be<br />
transliterated to camlCase identifiers possibly adding a (consistent)<br />
suffix or prefix to avoid conflicts with keywords. However, instead of<br />
a recurring prefix or suffix you may consider to use qualified imports<br />
and names.<br />
<br />
<br />
=== Good Programming Practice ===<br />
<br />
<br />
"Functions should be short and sweet, and do just one thing. They should<br />
fit on one or two screenfuls of text (the ISO/ANSI screen size is 80x24,<br />
as we all know), and do one thing and do that well."<br />
<br />
Most haskell functions should be at most a few lines, only case<br />
expression over large data types (that should be avoided, too) may need<br />
corresponding space.<br />
<br />
The code should be succinct (though not obfuscated), readable and easy to<br />
maintain (after unforeseeable changes). Don't exploit exotic language<br />
features without good reason.<br />
<br />
It's not fixed how deep you indent (4 or 8 chars). You can break the<br />
line after "do", "let", "where", and "case .. of". Make sure that<br />
renamings don't destroy your layout. (If you get to far to the right,<br />
the code is unreadable anyway and needs to be decomposed.)<br />
<br />
Bad:<br />
case foo of Foo -> "Foo"<br />
Bar -> "Bar"<br />
Good:<br />
case <longer expression> of<br />
Foo -> "Foo"<br />
Bar -> "Bar"<br />
<br />
Avoid the notation with braces and semicolons since the layout rule<br />
forces you to properly align your alternatives.<br />
<br />
Respect compiler warnings. Supply type signatures, avoid shadowing and<br />
unused variables. Particularly avoid non-exhaustive and<br />
overlapping patterns. Missing unreachable cases can be filled in using<br />
"error" with a fixed string "<ModuleName>.<function>" to indicate the<br />
error position (in case the impossible should happen). Don't invest<br />
time to "show" the offending value, only do this temporarily when<br />
debugging the code.<br />
<br />
Don't leave unused or commented-out code in your files! Readers don't<br />
know what to think of it.<br />
<br />
<br />
==== Case expressions ====<br />
<br />
Prefer case expressions over pattern binding declarations with<br />
multiple equations.<br />
<br />
Not always nice:<br />
longFunctionName (Foo: _ : _) = e1<br />
longFunctionName (Bar: _) = e2<br />
<br />
Better:<br />
longFunctionName arg = case arg of<br />
Foo : _ : _ -> e1<br />
Bar : _ -> e2<br />
_ -> error "ProgrammingGuidelines.longFunctionName"<br />
<br />
In<br />
http://research.microsoft.com/~simonpj/papers/haskell-retrospective/<br />
the first example is said to be written in [[declaration style]]. The<br />
equations look like written for a rewrite system (although their order<br />
matters of course).<br />
<br />
But this declarative style is only nice for toy examples and annoying<br />
if functions are renamed or if the number of arguments changes.<br />
<br />
The other extreme (according to SPJ) is [[expression style]]:<br />
longFunctionName = \ arg -> ...<br />
<br />
We don't propose this style either. We propose to use as much pattern<br />
matching (including as-patterns) on a single left-hand-side as appropriate.<br />
<br />
However, the expression style with a lambda term may come in handy, when<br />
setting record fields of a function type.<br />
<br />
We avoid lambda expressions if this is easily possibly using the<br />
Prelude functions const, flip, curry, uncurry or section notation or<br />
plain partial application. We do not introduce an auxiliary function only to<br />
avoid the lambda, though.<br />
<br />
==== Partial functions ====<br />
<br />
For partial functions do document their preconditions (if not obvious)<br />
and make sure that partial functions are only called when<br />
preconditions are obviously fulfilled (i.e. by a case statement or a<br />
previous test). Particularly the call of "head" should be used with<br />
care or (even better) be made obsolete by a case statement.<br />
<br />
Usually a case statement (and the import of isJust and fromJust from<br />
Data.[[Maybe]]) can be avoided by using the "maybe" function:<br />
<br />
maybe (error "<ModuleName>.<function>") id $ Map.lookup key map<br />
<br />
Generally we require you to be more explicit about failure<br />
cases. Surely a missing (or an irrefutable) pattern would precisely<br />
report the position of a runtime error, but these are not so obvious<br />
when reading the code.<br />
<br />
==== Let or where expressions ====<br />
<br />
Do avoid mixing and nesting "let" and "where". (I prefer the<br />
expression-stylistic "let".) Use auxiliary top-level functions that<br />
you do not export. Export lists also support the detection of unused<br />
functions.<br />
<br />
<br />
==== Code reuse ====<br />
<br />
If you notice that you're doing the same task again, try to generalize<br />
it in order to avoid duplicate code. It is frustrating to change the<br />
same error in several places.<br />
<br />
<br />
==== Application notation ====<br />
<br />
Many parentheses can be eliminated using the infix application operator "$"<br />
with lowest priority. Try at least to avoid unnecessary parentheses in<br />
standard infix expression.<br />
<br />
f x : g x ++ h x<br />
<br />
a == 1 && b == 1 || a == 0 && b == 0<br />
<br />
Rather than putting a large final argument in parentheses (with a<br />
distant closing one) consider using "$" instead.<br />
<br />
"f (g x)" becomes "f $ g x" and consecutive applications<br />
"f (g (h x))" can be written as "f $ g $ h x" or "f . g $ h x".<br />
<br />
A function definition like<br />
"f x = g $ h x" can be abbreviated to "f = g . h".<br />
<br />
Note that the final argument may even be an infix- or case expression:<br />
<br />
map id $ c : l<br />
<br />
filter (const True) . map id $ case l of ...<br />
<br />
However, be aware that $-terms cannot be composed further in infix<br />
expressions.<br />
<br />
Probably wrong:<br />
f $ x ++ g $ x<br />
<br />
But the scope of an expression is also limited by the layout rule, so<br />
it is usually safe to use "$" on right hand sides.<br />
<br />
Ok:<br />
do f $ l<br />
++<br />
do g $ l<br />
<br />
Of course "$" can not be used in types. GHC has also some primitive<br />
functions involving the kind "#" that cannot be applied using "$".<br />
<br />
Last warning: always leave spaces around "$" (and other mixfix<br />
operators) since a clash with template haskell is possible.<br />
<br />
(Also write "\ t" instead of "\t" in lambda expressions)<br />
<br />
<br />
==== List Comprehensions ====<br />
<br />
Use these only when "short and sweet". Prefer map, filter, and foldr!<br />
<br />
Instead of:<br />
<br />
[toUpper c | c <- s]<br />
<br />
write:<br />
<br />
map toUpper s<br />
<br />
<br />
Consider:<br />
<br />
[toUpper c | s <- strings, c <- s]<br />
<br />
Here it takes some time for the reader to find out which value depends<br />
on what other value and it is not so clear how many times the interim<br />
values s and c are used. In contrast to that the following can't be clearer:<br />
<br />
map toUpper (concat strings)<br />
<br />
<br />
When using higher order functions you can switch easier to data<br />
structures different from list. Compare:<br />
<br />
map (1+) list<br />
<br />
and:<br />
<br />
Set.map (1+) set<br />
<br />
<br />
==== Types ====<br />
<br />
Prefer proper data types over type synonyms or tuples even if you have<br />
to do more constructing and unpacking. This will make it easier to<br />
supply class instances later on. Don't put class constraints on<br />
a data type, constraints belong only to the functions that manipulate<br />
the data.<br />
<br />
Using type synonyms consistently is difficult over a longer time,<br />
because this is not checked by the compiler. (The types shown by<br />
the compiler may be unpredictable: i.e. FilePath, String or [Char])<br />
<br />
Take care if your data type has many variants (unless it is an<br />
enumeration type.) Don't repeat common parts in every variant since<br />
this will cause code duplication.<br />
<br />
Bad (to handle arguments in sync):<br />
<br />
data Mode f p = Box f p | Diamond f p<br />
<br />
Good (to handle arguments only once):<br />
<br />
data BoxOrDiamond = Box | Diamond<br />
<br />
data Mode f p = Mode BoxOrDiamond f p<br />
<br />
<br />
Consider (bad):<br />
<br />
data Tuple a b = Tuple a b | Undefined<br />
<br />
versus (better):<br />
<br />
data Tuple a b = Tuple a b<br />
<br />
and using:<br />
<br />
Maybe (Tuple a b)<br />
<br />
(or another monad) whenever an undefined result needs to be propagated<br />
<br />
<br />
==== Records ====<br />
<br />
For (large) records avoid the use of the constructor directly and<br />
remember that the order and number of fields may change.<br />
<br />
Take care with (the rare case of) depend polymorphic fields:<br />
<br />
data Fields a = VariantWithTwo<br />
{ field1 :: a<br />
, field2 :: a }<br />
<br />
The type of a value v can not be changed by only setting field1:<br />
<br />
v { field1 = f }<br />
<br />
Better construct a new value:<br />
<br />
VariantWithTwo { field1 = f } -- leaving field2 undefined<br />
<br />
Or use a polymorphic element that is instantiated by updating:<br />
<br />
empty = VariantWithTwo { field1 = [], field2 = [] }<br />
<br />
empty { field1 = [f] }<br />
<br />
Several variants with identical fields may avoid some code duplication<br />
when selecting and updating, though possibly not in a few<br />
depended polymorphic cases.<br />
<br />
However, I doubt if the following is a really good alternative to the<br />
above data Mode with data BoxOrDiamond.<br />
<br />
<br />
data Mode f p =<br />
Box { formula :: f, positions :: p }<br />
| Diamond { formula :: f, positions :: p }<br />
<br />
<br />
==== IO ====<br />
<br />
Try to strictly separate IO, Monad and pure (without do) function<br />
programming (possibly via separate modules).<br />
<br />
Bad:<br />
x <- return y<br />
...<br />
<br />
Good:<br />
let x = y<br />
...<br />
<br />
<br />
Don't use Prelude.interact and make sure your program does not depend<br />
on the (not always obvious) order of evaluation. I.e. don't read and<br />
write to the same file:<br />
<br />
This will fail:<br />
<br />
do s <- readFile f<br />
writeFile f $ 'a' : s<br />
<br />
because of lazy IO! (Writing is starting before reading is finished.)<br />
<br />
<br />
==== Trace ====<br />
<br />
Tracing is for debugging purposes only and should not be used as<br />
feedback for the user. Clean code is not cluttered by trace calls.<br />
<br />
<br />
==== Imports ====<br />
<br />
Standard library modules like Char. List, Maybe, Monad, etc should be<br />
imported by their hierarchical module name, i.e. the base package (so<br />
that haddock finds them):<br />
<br />
import Data.List<br />
import Control.Monad<br />
import System.Environment<br />
<br />
The libraries for Set and Map are to be imported qualified:<br />
<br />
import qualified Data.Set as Set<br />
import qualified Data.Map as Map<br />
<br />
<br />
==== Glasgow extensions and Classes ====<br />
<br />
[[Use of language extensions|Stay away from extensions]] as long as possible. Also use classes with<br />
care because soon the desire for overlapping instances (like for lists<br />
and strings) may arise. Then you may want MPTC (multi-parameter type<br />
classes), functional dependencies (FD), undecidable and possibly incoherent<br />
instances and then you are "in the wild" (according to SPJ).<br />
<br />
=== Style in other languages ===<br />
<br />
* [http://www.cs.caltech.edu/~cs20/a/style.html OCaml style]<br />
<br />
=== Final remarks ===<br />
<br />
Despite guidelines, writing "correct code" (without formal proof<br />
support yet) still remains the major challenge. As motivation to<br />
follow these guidelines consider the points that are from the "C++<br />
Coding Standard", where I replaced "C++" with "Haskell".<br />
<br />
Good Points:<br />
<br />
* programmers can go into any code and figure out what's going on<br />
<br />
* new people can get up to speed quickly<br />
<br />
* people new to Haskell are spared the need to develop a personal style and defend it to the death<br />
<br />
* people new to Haskell are spared making the same mistakes over and over again<br />
<br />
* people make fewer mistakes in consistent environments<br />
<br />
* programmers have a common enemy :-)<br />
<br />
Bad Points:<br />
<br />
* the standard is usually stupid because it was made by someone who doesn't understand Haskell<br />
<br />
* the standard is usually stupid because it's not what I do<br />
<br />
* standards reduce creativity<br />
<br />
* standards are unnecessary as long as people are consistent<br />
<br />
* standards enforce too much structure<br />
<br />
* people ignore standards anyway<br />
<br />
<br />
<br />
[[Category:Style]]</div>Jalexanderdatkinshttps://wiki.haskell.org/TypeType2012-07-31T10:57:24Z<p>Jalexanderdatkins: /* Type and newtype */ "field" -> "field label"</p>
<hr />
<div>In Haskell, '''types''' are how you describe the data your program will work with.<br />
<br />
[[Category:Language]]<br />
<br />
==Data declarations==<br />
<br />
One introduces, or declares, a type in Haskell via the <code>data</code> statement. In general a data declaration looks like:<br />
<br />
data [context =>] type tv1 ... tvi = con1 c1t1 c1t2... c1tn |<br />
... | conm cmt1 ... cmtq<br />
[deriving]<br />
<br />
which probably explains nothing if you don't already know Haskell!<br />
<br />
The essence of the above statement is that you use the keyword <hask>data</hask>,<br />
supply an optional context, give the type name and a variable number of <br />
[[type variable]]s. This is then followed by a variable number of [[constructor]]s, each of which has a list of [[type variable]]s or [[type constant]]s. At the end, there is an optional <code>deriving</code>.<br />
<br />
There are a number of other subtleties associated with this, such as requiring<br />
parameters to the data constructors to be [[eager]], what [[Type class|class]]es are<br />
allowed in the [[deriving]], use of [[field]] names in the constructors<br />
and what the [[context]] actually does. Please refer to the specific articles for more on each of those.<br />
<br />
Let's look at some examples. The Haskell standard data type [[Maybe]] is typically declared as:<br />
<haskell><br />
data Maybe a = Just a | Nothing<br />
</haskell><br />
What this means is that the type '''Maybe''' has one type variable, represented by the ''a'' and two [[constructor]]s '''Just''' and '''Nothing'''. (Note that Haskell requires type names and constructor names to begin with an uppercase letter). The '''Just''' constructor takes one parameter, of type ''a''.<br />
<br />
As another example, consider binary [[Tree]]s. They could be represented by:<br />
<haskell><br />
data Tree a = Branch (Tree a) (Tree a) | Leaf a<br />
</haskell><br />
Here, one of the constructors, '''Branch''' of '''Tree''' takes two trees as<br />
parameters to the constructor, while '''Leaf''' takes a value of type ''a''. This type of recursion is a very common [[:Category:Idioms |pattern]] in Haskell.<br />
<br />
==Type and newtype==<br />
<br />
The other two ways one may introduce types to Haskell programs are via the<br />
<hask>type</hask> and <hask>newtype</hask> statements.<br />
<br />
<hask>type</hask> introduces a synonym for a type and uses the same data<br />
constructors. <hask>newtype</hask> introduces a renaming of a type and <br />
requires you to provide new constructors.<br />
<br />
When using a <hask>type</hask> declaration, the type synonym and its base type<br />
are interchangeble almost everywhere (There are some restrictions when dealing with [[instance]] declarations). For example, if you had the declaration:<br />
<haskell><br />
type Name = String<br />
</haskell><br />
then any [[function]] you had declared that had <hask>String</hask> in its<br />
signature could be used on any element of type <code>Name</code><br />
<br />
However, if one had the declaration:<br />
<haskell> <br />
newtype FirstName = FirstName String<br />
</haskell><br />
this would no longer be the case. Functions would have to be declared that <br />
actually were defined on '''FirstName'''. Often, one creates a deconstructor<br />
at the same time which helps alleviate this requirement. e.g.:<br />
<haskell><br />
unFirstName :: FirstName -> String<br />
unFirstName (FirstName s) = s<br />
</haskell><br />
This is often done by the use of [[field|field labels]] in the <code>newtype</code>. (Note<br />
that many consider the Haskell field implementation sub-optimal, while <br />
others use it extensively. See [[Programming guidelines]] and [[Future of Haskell]])<br />
<br />
==A simple example==<br />
<br />
Suppose you want to create a program to play bridge. You need something to represent cards. Here is one way to do that.<br />
<br />
First, create data types for the suit and card number.<br />
<haskell><br />
data Suit = Club | Diamond | Heart | Spade<br />
deriving (Read, Show, Enum, Eq, Ord)<br />
<br />
data CardValue = Two | Three | Four<br />
| Five | Six | Seven | Eight | Nine | Ten <br />
| Jack | Queen | King | Ace<br />
deriving (Read, Show, Enum, Eq, Ord)<br />
</haskell><br />
Each of these uses a [[deriving]] clause to allow us to convert them from / to [[String]] and Int, test them for equality and ordering. With types like this, <br />
where there are no [[type variable]]s, equality is based upon which constructor is used and order is determined by the order you wrote them, e.g. <code>Three</code> is less than <code>Queen</code>.<br />
<br />
Now we define an actual <code>Card</code><br />
<haskell> <br />
data Card = Card {value :: CardValue, <br />
suit :: Suit}<br />
deriving (Read, Show, Eq)<br />
</haskell><br />
In this definition, we use [[field]]s, which give us ready made functions to<br />
access the two parts of a <code>Card</code>. Again, [[type variables]] were not<br />
used, but the data [[constructor]] requires its two parameters to be of<br />
specific types, <code>CardValue</code> and <code>Suit</code>.<br />
<br />
The deriving clause here only specifies three of our desired [[Type class|classes]], we supply [[instance]] declarations for [[Ord]] and [[Enum]]:<br />
<haskell><br />
instance Ord Card where<br />
compare c1 c2 = compare (value c1, suit c1) (value c2, suit c2)<br />
<br />
instance Enum Card where<br />
toEnum n = let (v,s) = n`divMod`4 in Card (toEnum v) (toEnum s)<br />
fromEnum c = fromEnum (value c) * 4 + fromEnum (suit c)<br />
</haskell><br />
Finally, we alias the type <code>Deck</code> to a list of <code>Card</code>s<br />
and populate the deck with a [[list comprehension]] <br />
<haskell><br />
type Deck = [Card]<br />
<br />
deck::Deck<br />
deck = [Card val su | val <- [Two .. Ace], su <- [Club .. Spade]]<br />
</haskell><br />
<br />
==Please add==<br />
<br />
Further illustrative examples would be most appreciated.<br />
<br />
==See also==<br />
Read the articles about data [[constructor]]s and [[Type class|class]]es. As well the<br />
[http://haskell.org/definition/haskell98-report.pdf Haskell 98 report] and<br />
your chosen implementation (e.g. [[GHC/Documentation]]) have the latest words.<br />
<br />
*[[Determining the type of an expression]] - Let the Haskell compiler compute the type of expression<br />
*[[:Category:Language extensions | Language extensions]] - many language extensions are to do with changes to the type system.<br />
*[[Smart constructors]] shows some interesting examples including a non-trivial usage of <code>newtype</code>.<br />
*[[Unboxed type]] shows ways to have values closer to the bare metal :).<br />
*[[Phantom type]] discusses types without constructors.<br />
*[[Type witness]] gives an example of [[Generalised algebraic datatype | GADTs]], a [[GHC]] extension.<br />
*[[Existential type]] shows how to implement a common O-O programming paradigm.<br />
*[[Type arithmetic]] implements the [[Peano numbers]].<br />
*[[Reified type]], [[Non-trivial type synonyms]], [[Abstract data type]], [[Concrete data type]], [[Algebraic data type]].<br />
*[[Research_papers/Type_systems]] allow the curious to delve deeper.<br />
<br />
Languages: [[型|ja]]</div>Jalexanderdatkins