2014-08-31 3 views
2

Learn You a Haskell обсуждает «Создание Монады» со следующими Prob типа:Конвертировать в стиль Pointfree?

import Data.Ratio 

newtype Prob a = Prob { getProb :: [(a,Rational)] } deriving Show 

Prob представляет a тип, а затем Rational, представляющая вероятность этого a используются.

Давайте посмотрим на Prob например:

*Main> Prob [('a', 1%2), ('b', 1%2)] 
Prob {getProb = [('a',1 % 2),('b',1 % 2)]} 

Лях создает упражнение, чтобы выяснить, как превратить thisSituation, типа Prob(Prob Char) в Prob Char:

thisSituation :: Prob (Prob Char) 
thisSituation = Prob 
    [(Prob [('a', 1%2),('b',1%2)], 1%4) 
    ,(Prob [('c', 1%2),('d',1%2)], 3%4) 
    ] 

Вот что я придумал:

flatten :: Prob (Prob a) -> Prob a 
flatten pp = Prob $ convert $ getProb pp 

convert :: [(Prob a, Rational)] -> [(a, Rational)] 
convert xs = concat $ map f xs 

f :: (Prob a, Rational) -> [(a, Rational)] 
f (p, r) = map (mult r) (getProb p) 

mult :: Rational -> (a, Rational) -> (a, Rational) 
mult r (x, y) = (x, r*y) 

Я попытался point-free, как так:

flatten :: Prob (Prob a) -> Prob a 
flatten = Prob $ convert $ getProb 

Но получил эту ошибку:

*Main> :l MakingMonad.hs 
[1 of 1] Compiling Main    (MakingMonad.hs, interpreted) 

MakingMonad.hs:37:11: 
    Couldn't match expected type `Prob (Prob a) -> Prob a' 
       with actual type `Prob a0' 
    In the expression: Prob $ convert $ getProb 
    In an equation for `flatten': flatten = Prob $ convert $ getProb 

MakingMonad.hs:37:28: 
    Couldn't match expected type `[(Prob a0, Rational)]' 
       with actual type `Prob a1 -> [(a1, Rational)]' 
    In the second argument of `($)', namely `getProb' 
    In the second argument of `($)', namely `convert $ getProb' 
    In the expression: Prob $ convert $ getProb 
Failed, modules loaded: none. 

Могу ли я сделать flatten точку бесплатно? Если да, пожалуйста, покажите мне, как это сделать. Если нет, объясните, почему.

+0

Изменение '$' в '' .' в flatten' –

ответ

7

При использовании $ в flatten, вы получите код, который выглядит

flatten = Prob $ convert $ getProb 
==> Prob (convert (getProb)) 

Который не то, что вы хотите.

Вы хотите Prob . convert . getProb

+0

так, если я понимаю, так как 'getProb' вложен в' Prob (конвертировать (', это не представляется возможным использовать точечно бесплатный стиль? Но, с функцией композиции, возможно –

+3

@KevinMeredith Когда вы пишете 'Prob (convert getProb)', вы передаете '(convert getProb)' в 'Prob' в качестве аргумента.' Prob' не принимает функции как аргументы, 'convert' также не принимает функции в качестве аргументов, поэтому вы получаете ошибки типа. –

+0

Это одна из причин, почему стиль' f. g. h $ x' часто предпочитается вместо 'f $ g $ hx' - проще конвертировать в и без тонального стиля. –

Смежные вопросы