2008/9/4 Timothy Goddard <[EMAIL PROTECTED]>: > It looks like this code isn't really in fitting with normal Haskell idioms.
I guess you mean by Haskell idiom : "pure". But Haskell allows you to do IO, etc. > Emulating C in Haskell will only give you a harder way of writing C. Don't > think about emulating a potentially null pointer with Maybe (IORef a) and > passing this to a function to read content unless you also want to implement > the function "segfault :: IO ()". > You really need to ask yourself whether it makes sense to read a NULL / > Nothing field. In C this would cause a segfault. The idea in Haskell is that > you don't allow invalid values to be passed in to a function at all. Each > function should be pure and accept only sensible inputs, allowing you to > analyse what each function does in isolation from the rest of the program. > > In Haskell, functions should use the type system to only accept arguments > which make sense. The caller should handle the possibility that a function it > calls returns nothing, not expect every other callee to do so. The Maybe > monad helps with this for many cases: > > lookupEmployee :: Integer -> Maybe Employee > lookupPassportNo :: Employee -> PassportNo > lookupMarriageCertificate :: PassportNo -> Maybe MarriageCert > getPassportNumbers :: MarriageCert -> (PassportNo, PassportNo) > getNameFromPassport :: PassportNo -> Maybe String > > lookupSpouse :: Integer -> Maybe String > lookupSpouse employee_no = do > employee <- lookupEmployee employee_no > let passport = lookupPassportNo employee > cert <- lookupMarriageCertificate > let (p1, p2) = getPassportNumbers cert > let partner = if p1 == passport then p2 else p1 > getNameFromPassport partner > > In this example, if any lookup which can fail does, the result is Nothing. > Each lookup function can assume that a valid argument is present, though some > types of lookup may still give no result. The caller chooses how to account > for this inability to find a match, in this case by itself having no result. Thanks for the exemple, but I'm aware of monads (even if I can't still use them easily when many of them are mixed). Here my problem is more about interactively editable data structure (at least from the point of view of the user). I would be very happy to do it with pure functions. > The thing I'm more concerned about here is the use of IORefs inside data > structures at all. A data structure containing IORefs is mutable and can only > be manipulated in the IO monad, which defeats the point of Haskell. There is > a use case for using mutable structures for some resource-intensive > operations, but even then it's often trading short-term speed for long term > difficulties. If you think immutable structures imply poor performance, take > a look at projects such as uvector and Data Parallel Haskell - immutable data > structures which beat the hell out traditional, C-like techniques. I'm looking at the FGL package, it seems very intersting. I don't think immutable data structures imply poor perfromance, but I think designing the examples you give is quite complicated and done by really experienced Haskell programmers. Please, don't answer to my problem (even if I haven't really explain it) by exposing state-of-the-art Haskell goodness. > If you must use IORefs, consider only using them to hold the whole structure, > which is modified by normal, pure functions. If you don't think you can make > do with this, you're probably still thinking about the program in an > imperative manner. You will probably be better off either rethinking how > you're doing things or, if you cannot translate the concepts to a functional > form, using an imperative language. Overall, I agree I have to look for a more pure approach. Although, I think something like FGL required a lot of work. But raising, say, uvector, in face of my use of IORef seems a bit quick. > Good luck, Thank you, Thu > > Tim > > On Wed, 03 Sep 2008 22:09:38 minh thu wrote: >> Hi, >> >> I'd like to write a data structure to be used inside the IO monad. >> The structure has some handles of type Maybe (IORef a), >> i.e. IORef are pointers and the Maybe is like null pointers. >> >> So I came up with the following functions : >> >> readHandle :: Maybe (IORef a) -> IO (Maybe a) >> readField :: (a -> b) -> Maybe (IORef a) -> IO (Maybe b) >> >> readHandle Nothing = do >> return Nothing >> readHandle (Just r) = do >> v <- readIORef r >> return $ Just v >> >> readField f h = do >> m <- readHandle h >> return $ fmap f m >> >> Is it something usual ? >> Are there any related functions in the standard libraries ? >> >> Thanks, >> Thu >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe