logo
首页技术栈工具库讨论
mtl-evil-instances
mtl-evil-instances
Deprecated in favor of layers WARNING: THIS PACKAGE IS EVIL. DO NOT USE IT! It is common when defining a monad transformer to define instances for that transformer for each class in the mtl library, to allow easy composition with the existing standard monad transformers. However, doing this is very tedious, and actually unnecessary, given that most of these instances across different transformers are identical, and can actually be expressed purely in terms of MonadTrans, or MonadTransControl (from the monad-control package) for the more complicated classes. The reason this is not generally done is because it requires the OverlappingInstances extension, which is generally considered evil. However, it does actually work. If you define a monad transformer, and instances for MonadTrans and MonadTransControl, and import Control.Monad.Instances.Overlapping, your monad transformer will magically have sensible instances for all the mtl type classes. And if you don't like one of the instances provided, you can always define your own instance, which will override the "default" one provided by this package, because by the rules for OverlappingInstances, your instance is more "specific" than the one exported by Control.Monad.Instances.Overlapping. The main disadvantage of this is that errors in code using OverlappingInstances can result in some really strange error messages that are not very helpful. The reason this is evil is because this places an additional burden (of dealing with confusing error messages) not just on those who use this package directly, but anybody who indirectly uses any code that, somewhere down the line, imported Control.Monad.Instances.Overlapping, due to the "viral" nature of instances. Also, if another person were to make a package very similar to this one, and somebody ended up importing both code that used this package, and code that used the other package, than neither of them would work anymore. This is the problem with orphan instances. If you absolutely insist on using this code, you should probably define manual instances for the mtl classes the hard way as well, to avoid this kind of breakage (thus defeating the purpose of this package). Of course, realistically, this package is for everyone who wishes to ignore all such advice and do bad things anyway (including myself). This is my gift to you!
Win32-services
Win32-services
This package provides a partial binding to the Win32 System Services API. It makes it easy to write Windows service applications using Haskell. _Only 32-bit versions of GHC are supported at this time._ The binding is partial. Here are a few ways in which it differs from the official API: Only services running within their own process are supported. These are processes of the WIN32_OWN_PROCESS type. In cases where multiple versions of the same function exist (for compatibility), this binding only offers one of them. None of the extended control codes are supported. Handlers you write will automatically report this to the operating system when such controls are received. Only facilities for writing services are supported; not controlling them. Effort has been made to simplify using the API without hiding what is happening behind the scenes. Users are encouraged to read Microsoft's documentation under 'Dev Center - Desktop > Docs > Desktop app development documentation > System Services > Services'. The official example has been ported to Haskell. This can be found in the examples directory of the source tree. Simple Example and Usage Execute the following from an elevated command prompt to register the service: The service can now be started and stopped from the services console. Installation Notes: Depending on which version of Windows and the Windows SDK you are using the .cabal file will need to be modified before installing. A simple `cabal install Win32-services` may not work. For example, If you are building on Windows 8 64-bit with the Windows 8 SDK the extra-lib-dirs field will need to be changed to read as follows: