packages feed

Data-Angle (empty) → 0.9

raw patch · 43 files changed

+768/−0 lines, 43 filesdep +basesetup-changedbinary-added

Dependencies added: base

Files

+ .git/COMMIT_EDITMSG view
@@ -0,0 +1,1 @@+Commit committed
+ .git/FETCH_HEAD view
@@ -0,0 +1,1 @@+b76f91fdd657bb098db6a5bead1b7b38fb3a0199		branch 'master' of https://github.com/deadmanswitch/Data.Angle
+ .git/HEAD view
@@ -0,0 +1,1 @@+ref: refs/heads/master
+ .git/config view
@@ -0,0 +1,13 @@+[core]+	repositoryformatversion = 0+	filemode = false+	bare = false+	logallrefupdates = true+	symlinks = false+	ignorecase = true+[remote "origin"]+	url = https://github.com/deadmanswitch/Data.Angle.git+	fetch = +refs/heads/*:refs/remotes/origin/*+[branch "master"]+	remote = origin+	merge = refs/heads/master
+ .git/description view
@@ -0,0 +1,1 @@+Unnamed repository; edit this file 'description' to name the repository.
+ .git/hooks/applypatch-msg.sample view
@@ -0,0 +1,15 @@+#!/bin/sh+#+# An example hook script to check the commit log message taken by+# applypatch from an e-mail message.+#+# The hook should exit with non-zero status after issuing an+# appropriate message if it wants to stop the commit.  The hook is+# allowed to edit the commit message file.+#+# To enable this hook, rename this file to "applypatch-msg".++. git-sh-setup+commitmsg="$(git rev-parse --git-path hooks/commit-msg)"+test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"}+:
+ .git/hooks/commit-msg.sample view
@@ -0,0 +1,24 @@+#!/bin/sh+#+# An example hook script to check the commit log message.+# Called by "git commit" with one argument, the name of the file+# that has the commit message.  The hook should exit with non-zero+# status after issuing an appropriate message if it wants to stop the+# commit.  The hook is allowed to edit the commit message file.+#+# To enable this hook, rename this file to "commit-msg".++# Uncomment the below to add a Signed-off-by line to the message.+# Doing this in a hook is a bad idea in general, but the prepare-commit-msg+# hook is more suited to it.+#+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"++# This example catches duplicate Signed-off-by lines.++test "" = "$(grep '^Signed-off-by: ' "$1" |+	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {+	echo >&2 Duplicate Signed-off-by lines.+	exit 1+}
+ .git/hooks/post-update.sample view
@@ -0,0 +1,8 @@+#!/bin/sh+#+# An example hook script to prepare a packed repository for use over+# dumb transports.+#+# To enable this hook, rename this file to "post-update".++exec git update-server-info
+ .git/hooks/pre-applypatch.sample view
@@ -0,0 +1,14 @@+#!/bin/sh+#+# An example hook script to verify what is about to be committed+# by applypatch from an e-mail message.+#+# The hook should exit with non-zero status after issuing an+# appropriate message if it wants to stop the commit.+#+# To enable this hook, rename this file to "pre-applypatch".++. git-sh-setup+precommit="$(git rev-parse --git-path hooks/pre-commit)"+test -x "$precommit" && exec "$precommit" ${1+"$@"}+:
+ .git/hooks/pre-commit.sample view
@@ -0,0 +1,49 @@+#!/bin/sh+#+# An example hook script to verify what is about to be committed.+# Called by "git commit" with no arguments.  The hook should+# exit with non-zero status after issuing an appropriate message if+# it wants to stop the commit.+#+# To enable this hook, rename this file to "pre-commit".++if git rev-parse --verify HEAD >/dev/null 2>&1+then+	against=HEAD+else+	# Initial commit: diff against an empty tree object+	against=4b825dc642cb6eb9a060e54bf8d69288fbee4904+fi++# If you want to allow non-ASCII filenames set this variable to true.+allownonascii=$(git config --bool hooks.allownonascii)++# Redirect output to stderr.+exec 1>&2++# Cross platform projects tend to avoid non-ASCII filenames; prevent+# them from being added to the repository. We exploit the fact that the+# printable range starts at the space character and ends with tilde.+if [ "$allownonascii" != "true" ] &&+	# Note that the use of brackets around a tr range is ok here, (it's+	# even required, for portability to Solaris 10's /usr/bin/tr), since+	# the square bracket bytes happen to fall in the designated range.+	test $(git diff --cached --name-only --diff-filter=A -z $against |+	  LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0+then+	cat <<\EOF+Error: Attempt to add a non-ASCII file name.++This can cause problems if you want to work with people on other platforms.++To be portable it is advisable to rename the file.++If you know what you are doing you can disable this check using:++  git config hooks.allownonascii true+EOF+	exit 1+fi++# If there are whitespace errors, print the offending file names and fail.+exec git diff-index --check --cached $against --
+ .git/hooks/pre-push.sample view
@@ -0,0 +1,53 @@+#!/bin/sh++# An example hook script to verify what is about to be pushed.  Called by "git+# push" after it has checked the remote status, but before anything has been+# pushed.  If this script exits with a non-zero status nothing will be pushed.+#+# This hook is called with the following parameters:+#+# $1 -- Name of the remote to which the push is being done+# $2 -- URL to which the push is being done+#+# If pushing without using a named remote those arguments will be equal.+#+# Information about the commits which are being pushed is supplied as lines to+# the standard input in the form:+#+#   <local ref> <local sha1> <remote ref> <remote sha1>+#+# This sample shows how to prevent push of commits where the log message starts+# with "WIP" (work in progress).++remote="$1"+url="$2"++z40=0000000000000000000000000000000000000000++while read local_ref local_sha remote_ref remote_sha+do+	if [ "$local_sha" = $z40 ]+	then+		# Handle delete+		:+	else+		if [ "$remote_sha" = $z40 ]+		then+			# New branch, examine all commits+			range="$local_sha"+		else+			# Update to existing branch, examine new commits+			range="$remote_sha..$local_sha"+		fi++		# Check for WIP commit+		commit=`git rev-list -n 1 --grep '^WIP' "$range"`+		if [ -n "$commit" ]+		then+			echo >&2 "Found WIP commit in $local_ref, not pushing"+			exit 1+		fi+	fi+done++exit 0
+ .git/hooks/pre-rebase.sample view
@@ -0,0 +1,169 @@+#!/bin/sh+#+# Copyright (c) 2006, 2008 Junio C Hamano+#+# The "pre-rebase" hook is run just before "git rebase" starts doing+# its job, and can prevent the command from running by exiting with+# non-zero status.+#+# The hook is called with the following parameters:+#+# $1 -- the upstream the series was forked from.+# $2 -- the branch being rebased (or empty when rebasing the current branch).+#+# This sample shows how to prevent topic branches that are already+# merged to 'next' branch from getting rebased, because allowing it+# would result in rebasing already published history.++publish=next+basebranch="$1"+if test "$#" = 2+then+	topic="refs/heads/$2"+else+	topic=`git symbolic-ref HEAD` ||+	exit 0 ;# we do not interrupt rebasing detached HEAD+fi++case "$topic" in+refs/heads/??/*)+	;;+*)+	exit 0 ;# we do not interrupt others.+	;;+esac++# Now we are dealing with a topic branch being rebased+# on top of master.  Is it OK to rebase it?++# Does the topic really exist?+git show-ref -q "$topic" || {+	echo >&2 "No such branch $topic"+	exit 1+}++# Is topic fully merged to master?+not_in_master=`git rev-list --pretty=oneline ^master "$topic"`+if test -z "$not_in_master"+then+	echo >&2 "$topic is fully merged to master; better remove it."+	exit 1 ;# we could allow it, but there is no point.+fi++# Is topic ever merged to next?  If so you should not be rebasing it.+only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`+only_next_2=`git rev-list ^master           ${publish} | sort`+if test "$only_next_1" = "$only_next_2"+then+	not_in_topic=`git rev-list "^$topic" master`+	if test -z "$not_in_topic"+	then+		echo >&2 "$topic is already up-to-date with master"+		exit 1 ;# we could allow it, but there is no point.+	else+		exit 0+	fi+else+	not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`+	/usr/bin/perl -e '+		my $topic = $ARGV[0];+		my $msg = "* $topic has commits already merged to public branch:\n";+		my (%not_in_next) = map {+			/^([0-9a-f]+) /;+			($1 => 1);+		} split(/\n/, $ARGV[1]);+		for my $elem (map {+				/^([0-9a-f]+) (.*)$/;+				[$1 => $2];+			} split(/\n/, $ARGV[2])) {+			if (!exists $not_in_next{$elem->[0]}) {+				if ($msg) {+					print STDERR $msg;+					undef $msg;+				}+				print STDERR " $elem->[1]\n";+			}+		}+	' "$topic" "$not_in_next" "$not_in_master"+	exit 1+fi++exit 0++################################################################++This sample hook safeguards topic branches that have been+published from being rewound.++The workflow assumed here is:++ * Once a topic branch forks from "master", "master" is never+   merged into it again (either directly or indirectly).++ * Once a topic branch is fully cooked and merged into "master",+   it is deleted.  If you need to build on top of it to correct+   earlier mistakes, a new topic branch is created by forking at+   the tip of the "master".  This is not strictly necessary, but+   it makes it easier to keep your history simple.++ * Whenever you need to test or publish your changes to topic+   branches, merge them into "next" branch.++The script, being an example, hardcodes the publish branch name+to be "next", but it is trivial to make it configurable via+$GIT_DIR/config mechanism.++With this workflow, you would want to know:++(1) ... if a topic branch has ever been merged to "next".  Young+    topic branches can have stupid mistakes you would rather+    clean up before publishing, and things that have not been+    merged into other branches can be easily rebased without+    affecting other people.  But once it is published, you would+    not want to rewind it.++(2) ... if a topic branch has been fully merged to "master".+    Then you can delete it.  More importantly, you should not+    build on top of it -- other people may already want to+    change things related to the topic as patches against your+    "master", so if you need further changes, it is better to+    fork the topic (perhaps with the same name) afresh from the+    tip of "master".++Let's look at this example:++		   o---o---o---o---o---o---o---o---o---o "next"+		  /       /           /           /+		 /   a---a---b A     /           /+		/   /               /           /+	       /   /   c---c---c---c B         /+	      /   /   /             \         /+	     /   /   /   b---b C     \       /+	    /   /   /   /             \     /+    ---o---o---o---o---o---o---o---o---o---o---o "master"+++A, B and C are topic branches.++ * A has one fix since it was merged up to "next".++ * B has finished.  It has been fully merged up to "master" and "next",+   and is ready to be deleted.++ * C has not merged to "next" at all.++We would want to allow C to be rebased, refuse A, and encourage+B to be deleted.++To compute (1):++	git rev-list ^master ^topic next+	git rev-list ^master        next++	if these match, topic has not merged in next at all.++To compute (2):++	git rev-list master..topic++	if this is empty, it is fully merged to "master".
+ .git/hooks/pre-receive.sample view
@@ -0,0 +1,24 @@+#!/bin/sh+#+# An example hook script to make use of push options.+# The example simply echoes all push options that start with 'echoback='+# and rejects all pushes when the "reject" push option is used.+#+# To enable this hook, rename this file to "pre-receive".++if test -n "$GIT_PUSH_OPTION_COUNT"+then+	i=0+	while test "$i" -lt "$GIT_PUSH_OPTION_COUNT"+	do+		eval "value=\$GIT_PUSH_OPTION_$i"+		case "$value" in+		echoback=*)+			echo "echo from the pre-receive-hook: ${value#*=}" >&2+			;;+		reject)+			exit 1+		esac+		i=$((i + 1))+	done+fi
+ .git/hooks/prepare-commit-msg.sample view
@@ -0,0 +1,36 @@+#!/bin/sh+#+# An example hook script to prepare the commit log message.+# Called by "git commit" with the name of the file that has the+# commit message, followed by the description of the commit+# message's source.  The hook's purpose is to edit the commit+# message file.  If the hook fails with a non-zero status,+# the commit is aborted.+#+# To enable this hook, rename this file to "prepare-commit-msg".++# This hook includes three examples.  The first comments out the+# "Conflicts:" part of a merge commit.+#+# The second includes the output of "git diff --name-status -r"+# into the message, just before the "git status" output.  It is+# commented because it doesn't cope with --amend or with squashed+# commits.+#+# The third example adds a Signed-off-by line to the message, that can+# still be edited.  This is rarely a good idea.++case "$2,$3" in+  merge,)+    /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;++# ,|template,)+#   /usr/bin/perl -i.bak -pe '+#      print "\n" . `git diff --cached --name-status -r`+#	 if /^#/ && $first++ == 0' "$1" ;;++  *) ;;+esac++# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
+ .git/hooks/update.sample view
@@ -0,0 +1,128 @@+#!/bin/sh+#+# An example hook script to block unannotated tags from entering.+# Called by "git receive-pack" with arguments: refname sha1-old sha1-new+#+# To enable this hook, rename this file to "update".+#+# Config+# ------+# hooks.allowunannotated+#   This boolean sets whether unannotated tags will be allowed into the+#   repository.  By default they won't be.+# hooks.allowdeletetag+#   This boolean sets whether deleting tags will be allowed in the+#   repository.  By default they won't be.+# hooks.allowmodifytag+#   This boolean sets whether a tag may be modified after creation. By default+#   it won't be.+# hooks.allowdeletebranch+#   This boolean sets whether deleting branches will be allowed in the+#   repository.  By default they won't be.+# hooks.denycreatebranch+#   This boolean sets whether remotely creating branches will be denied+#   in the repository.  By default this is allowed.+#++# --- Command line+refname="$1"+oldrev="$2"+newrev="$3"++# --- Safety check+if [ -z "$GIT_DIR" ]; then+	echo "Don't run this script from the command line." >&2+	echo " (if you want, you could supply GIT_DIR then run" >&2+	echo "  $0 <ref> <oldrev> <newrev>)" >&2+	exit 1+fi++if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then+	echo "usage: $0 <ref> <oldrev> <newrev>" >&2+	exit 1+fi++# --- Config+allowunannotated=$(git config --bool hooks.allowunannotated)+allowdeletebranch=$(git config --bool hooks.allowdeletebranch)+denycreatebranch=$(git config --bool hooks.denycreatebranch)+allowdeletetag=$(git config --bool hooks.allowdeletetag)+allowmodifytag=$(git config --bool hooks.allowmodifytag)++# check for no description+projectdesc=$(sed -e '1q' "$GIT_DIR/description")+case "$projectdesc" in+"Unnamed repository"* | "")+	echo "*** Project description file hasn't been set" >&2+	exit 1+	;;+esac++# --- Check types+# if $newrev is 0000...0000, it's a commit to delete a ref.+zero="0000000000000000000000000000000000000000"+if [ "$newrev" = "$zero" ]; then+	newrev_type=delete+else+	newrev_type=$(git cat-file -t $newrev)+fi++case "$refname","$newrev_type" in+	refs/tags/*,commit)+		# un-annotated tag+		short_refname=${refname##refs/tags/}+		if [ "$allowunannotated" != "true" ]; then+			echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2+			echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2+			exit 1+		fi+		;;+	refs/tags/*,delete)+		# delete tag+		if [ "$allowdeletetag" != "true" ]; then+			echo "*** Deleting a tag is not allowed in this repository" >&2+			exit 1+		fi+		;;+	refs/tags/*,tag)+		# annotated tag+		if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1+		then+			echo "*** Tag '$refname' already exists." >&2+			echo "*** Modifying a tag is not allowed in this repository." >&2+			exit 1+		fi+		;;+	refs/heads/*,commit)+		# branch+		if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then+			echo "*** Creating a branch is not allowed in this repository" >&2+			exit 1+		fi+		;;+	refs/heads/*,delete)+		# delete branch+		if [ "$allowdeletebranch" != "true" ]; then+			echo "*** Deleting a branch is not allowed in this repository" >&2+			exit 1+		fi+		;;+	refs/remotes/*,commit)+		# tracking branch+		;;+	refs/remotes/*,delete)+		# delete tracking branch+		if [ "$allowdeletebranch" != "true" ]; then+			echo "*** Deleting a tracking branch is not allowed in this repository" >&2+			exit 1+		fi+		;;+	*)+		# Anything else (is there anything else?)+		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2+		exit 1+		;;+esac++# --- Finished+exit 0
+ .git/index view

binary file changed (absent → 578 bytes)

+ .git/info/exclude view
@@ -0,0 +1,6 @@+# git ls-files --others --exclude-from=.git/info/exclude+# Lines that start with '#' are comments.+# For a project mostly in C, the following would be a good set of+# exclude patterns (uncomment them if you want to use them):+# *.[oa]+# *~
+ .git/logs/HEAD view
@@ -0,0 +1,2 @@+0000000000000000000000000000000000000000 edb2ad6987f8eb1c4df5bf4508236ed0b32f91ad deadmanswitch <kecskes.adam@outlook.com> 1490528741 +0200	clone: from https://github.com/deadmanswitch/Data.Angle.git+edb2ad6987f8eb1c4df5bf4508236ed0b32f91ad b76f91fdd657bb098db6a5bead1b7b38fb3a0199 deadmanswitch <kecskes.adam@outlook.com> 1490529090 +0200	commit: Commit committed
+ .git/logs/refs/heads/master view
@@ -0,0 +1,2 @@+0000000000000000000000000000000000000000 edb2ad6987f8eb1c4df5bf4508236ed0b32f91ad deadmanswitch <kecskes.adam@outlook.com> 1490528741 +0200	clone: from https://github.com/deadmanswitch/Data.Angle.git+edb2ad6987f8eb1c4df5bf4508236ed0b32f91ad b76f91fdd657bb098db6a5bead1b7b38fb3a0199 deadmanswitch <kecskes.adam@outlook.com> 1490529090 +0200	commit: Commit committed
+ .git/logs/refs/remotes/origin/HEAD view
@@ -0,0 +1,1 @@+0000000000000000000000000000000000000000 edb2ad6987f8eb1c4df5bf4508236ed0b32f91ad deadmanswitch <kecskes.adam@outlook.com> 1490528741 +0200	clone: from https://github.com/deadmanswitch/Data.Angle.git
+ .git/logs/refs/remotes/origin/master view
@@ -0,0 +1,1 @@+edb2ad6987f8eb1c4df5bf4508236ed0b32f91ad b76f91fdd657bb098db6a5bead1b7b38fb3a0199 deadmanswitch <kecskes.adam@outlook.com> 1490529108 +0200	update by push
+ .git/objects/06/cdb51daa6588347ecd9719542b9018c3c47f70 view

binary file changed (absent → 79 bytes)

+ .git/objects/10/c7435e20108e051bda0bc4fc15ccf1f0c20c6e view

binary file changed (absent → 360 bytes)

+ .git/objects/1a/169a9936954fdc15d3ecfcc4b1a62109f4ecd7 view

binary file changed (absent → 222 bytes)

+ .git/objects/3c/020def903d937df865c3028bdbb516bd09efb2 view

binary file changed (absent → 819 bytes)

+ .git/objects/5a/81bc6a763f9e8417f137cd63439d53f0ecb7e0 view

binary file changed (absent → 52 bytes)

+ .git/objects/9a/994af677b0dfd41b4e3b76b3e7e604003d64e1 view

binary file changed (absent → 59 bytes)

+ .git/objects/a4/ee41ab62b01d5467e6b817aa1107606ba478d4 view
@@ -0,0 +1,3 @@+x5ŒÁÂ0C9ç+8OjâÀç 4íÖ²ª©Öҍ¿'ÓÆ!ϲÛ&±×ûóqq±6Øa`²”Œó½|²bPç¾ùµG»j€¡°¢ú܏z¥ì¬l·c
O‹,yŒ“6Ë"£+}6e(+ß}nI&Àڈg³Ê2ÿëúýöÜ0	S‚q:S
+ .git/objects/aa/893d7416c4ceb262302c0f260f5784c0b06161 view

binary file changed (absent → 46 bytes)

+ .git/objects/af/5c552aff3ca42f459aff2188117dabecd04925 view

binary file changed (absent → 88 bytes)

+ .git/objects/b7/6f91fdd657bb098db6a5bead1b7b38fb3a0199 view

binary file changed (absent → 163 bytes)

+ .git/objects/ed/b2ad6987f8eb1c4df5bf4508236ed0b32f91ad view
@@ -0,0 +1,2 @@+x­ŽA+Â0E]÷³J2&µ·cšLl i$"Þހ+÷îþ{‹Ç÷%ç$€ˆ©Ì@Ñzk‘b<y2um£G­Ï&öA‡¶£]æR!0…LëöJâg¸üàm߸nýZ*?—wÿH2ïSïK¾‚6NYÜ0ÂQ¡R]³í‡ðÿŠÝ}M’hoúE×M
+ .git/objects/ff/85101b2570140fe938963236ff3f28a5659a72 view

binary file changed (absent → 1107 bytes)

+ .git/packed-refs view
@@ -0,0 +1,2 @@+# pack-refs with: peeled fully-peeled +edb2ad6987f8eb1c4df5bf4508236ed0b32f91ad refs/remotes/origin/master
+ .git/refs/heads/master view
@@ -0,0 +1,1 @@+b76f91fdd657bb098db6a5bead1b7b38fb3a0199
+ .git/refs/remotes/origin/HEAD view
@@ -0,0 +1,1 @@+ref: refs/remotes/origin/master
+ .git/refs/remotes/origin/master view
@@ -0,0 +1,1 @@+b76f91fdd657bb098db6a5bead1b7b38fb3a0199
+ .gitignore view
@@ -0,0 +1,19 @@+dist
+dist-*
+cabal-dev
+*.o
+*.hi
+*.chi
+*.chs.h
+*.dyn_o
+*.dyn_hi
+.hpc
+.hsenv
+.cabal-sandbox/
+cabal.sandbox.config
+*.prof
+*.aux
+*.hp
+*.eventlog
+.stack-work/
+cabal.project.local
+ Data-Angle.cabal view
@@ -0,0 +1,23 @@+name:                Data-Angle
+version:             0.9
+synopsis:            Geometric angles
+description:         A library for dealing with geometric angles (Degrees, Turns, Radians). For the sake of simplicity, the angles are represented in Radians
+license:             BSD3
+license-file:        LICENSE
+author:              Adam Kecskes
+maintainer:          kecskes.adam@outlook.com
+homepage:            https://github.com/deadmanswitch/Data.Angle
+bug-reports:         https://github.com/deadmanswitch/Data.Angle/issues
+category:            Data, Math
+build-type:          Simple
+cabal-version:       >=1.10
+
+source-repository head
+    type: git
+    location: https://github.com/deadmanswitch/Data.Angle
+
+library
+  exposed-modules:     Data.Angle
+  build-depends:       base >=4.9 && <5
+  hs-source-dirs:      src
+  default-language:    Haskell2010
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2017, Adam Kecskes
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Adam Kecskes nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,2 @@+# Data.Angle
+A Haskell library for dealing with geometric angles
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple
+main = defaultMain
+ src/Data/Angle.hs view
@@ -0,0 +1,133 @@+
+module Data.Angle where
+
+import Data.Fixed -- mod'
+
+newtype Angle a = Radians { angleValueRadians :: a } deriving (Eq, Show)
+
+
+-- Creating Angle from a value
+
+
+-- | Create an Angle with the given degrees
+angleFromDegrees :: (Integral d, Floating r) => d -> Angle r
+angleFromDegrees x = Radians $ (realToFrac x) * pi/180
+
+-- | Create an Angle with the given turns
+angleFromTurns :: (Real t, Floating r) => t -> Angle r
+angleFromTurns x = Radians $ (realToFrac x) * pi*2
+
+-- | Create an Angle with the given turns
+angleFromRadians :: (Floating r) => r -> Angle r
+angleFromRadians = Radians
+
+
+-- Get the value from angle
+
+
+-- | Get degrees from an angle
+angleValueDegrees :: (Floating r, RealFrac r, Integral d) => Angle r -> d
+angleValueDegrees (Radians x) = round $ x / pi * 180.0
+
+-- | Get turns from an angle
+angleValueTurns :: (Floating r) => Angle r -> r
+angleValueTurns (Radians x) = x / (pi*2)
+
+
+-- Functor and Applicative instance
+
+
+instance Functor Angle where
+    fmap f (Radians x) = Radians (f x)
+
+instance Applicative Angle where
+    pure = Radians       
+    Radians f <*> r = fmap f r
+
+
+-- Basic functions
+
+
+-- | Adding two angles
+addAngle :: (Floating a) => Angle a -> Angle a -> Angle a
+addAngle r1 r2 = (+) <$> r1 <*> r2
+
+-- | Normalize Angle: transforming back to (0-2pi)
+normAngle :: (Floating a, Real a) => Angle a -> Angle a
+normAngle (Radians r) = Radians $ mod' r (pi*2)
+
+-- | Add two angles and normalize the result
+addAngleNorm :: (Floating a, Real a) => Angle a -> Angle a -> Angle a
+addAngleNorm a b = normAngle $ addAngle a b
+
+-- | Distance between two angles
+distAngle :: (Floating a, Real a) => Angle a -> Angle a -> Angle a
+distAngle (Radians r1) (Radians r2) = Radians $ if (a' < b') then a' else b'
+    where
+        a' = mod' (r1-r2) (pi*2)
+        b' = mod' (r2-r1) (pi*2)
+
+-- | Flip angle
+flipAngle :: (Floating a) => Angle a -> Angle a
+flipAngle = fmap negate
+
+-- | Flip angle and normalize the result
+flipAngleNorm :: (Floating a, Real a) => Angle a -> Angle a
+flipAngleNorm = normAngle . flipAngle
+
+-- | Add degrees to angle
+addAngleDegrees :: (Floating r, Integral d) => Angle r -> d -> Angle r
+addAngleDegrees ang deg = addAngle ang $ angleFromDegrees deg
+
+-- | Add radians to angle
+addAngleRadians :: (Floating r) => Angle r -> r -> Angle r
+addAngleRadians (Radians r1) r2 = Radians $ r1 + r2
+
+-- | Add turns to angle
+addAngleTurns :: (Floating r, Real t) => Angle r -> t -> Angle r
+addAngleTurns ang turn = addAngle ang $ angleFromTurns turn
+
+-- Trigonometric functions
+
+
+-- | Sine of the angle
+sinAngle :: (Floating a) => Angle a -> a
+sinAngle = sin . angleValueRadians
+
+-- | Cosine of the angle
+cosAngle :: (Floating a) => Angle a -> a
+cosAngle = cos . angleValueRadians
+
+-- | Tangent of the angle
+tanAngle :: (Floating a) => Angle a -> a
+tanAngle = tan . angleValueRadians
+
+-- | Cotangent of the angle
+cotAngle :: (Floating a) => Angle a -> a
+cotAngle = recip . tan . angleValueRadians
+
+
+-- Inverse trigonometric functions
+
+
+-- | Create angle from inverse sine
+asinAngle :: (Floating a) => a -> Angle a
+asinAngle = Radians . asin
+
+-- | Create angle from inverse cosine
+acosAngle :: (Floating a) => a -> Angle a
+acosAngle = Radians . acos
+
+-- | Create angle from inverse tangent
+atanAngle :: (Floating a) => a -> Angle a
+atanAngle = Radians . atan
+
+-- | Create angle from inverse cotangent
+acotAngle :: (Floating a) => a -> Angle a
+acotAngle x = Radians $ (pi/2) - (atan x)
+
+
+-- | Create angle from atan2
+atan2Angle :: (Floating a, RealFloat a) => a -> a -> Angle a
+atan2Angle y x = Radians $ atan2 y x
+