diff options
| author | Joey Hess <joeyh@joeyh.name> | 2015-01-24 16:54:49 -0400 |
|---|---|---|
| committer | Joey Hess <joeyh@joeyh.name> | 2015-01-24 16:54:49 -0400 |
| commit | 45c94ffdd79b4f8134ef651b08fedb57b37448e6 (patch) | |
| tree | f6f156c9281d91654d1a7675841ac1bf3adab715 /src/Propellor/Info.hs | |
| parent | 414ee7eee60300eb7f7c49e4890b056d19b3c59b (diff) | |
moving to using the GADT
The problem this exposes has to do with requires. As implemented,
requires yields either a Property HasInfo or a Property NoInfo depending
on its inputs. That works. But look what happens when it's used:
*Propellor.Types> let foo = IProperty "foo" (return NoChange) mempty mempty
*Propellor.Types> let bar = IProperty "bar" (return NoChange) mempty mempty
*Propellor.Types> foo `requires` bar
<interactive>:17:5:
No instance for (Requires (Property HasInfo) (Property HasInfo) r0)
arising from a use of `requires'
The type variable `r0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there is a potential instance available:
instance Requires
(Property HasInfo) (Property HasInfo) (Property HasInfo)
-- Defined at Propellor/Types.hs:167:10
Possible fix:
add an instance declaration for
(Requires (Property HasInfo) (Property HasInfo) r0)
In the expression: foo `requires` bar
In an equation for `it': it = foo `requires` bar
This can be avoided by specifying the result type:
*Propellor.Types> (foo `requires` bar) :: Property HasInfo
property "foo"
But then when multiple `requires` are given, the result type has to be
given each time:
*Propellor.Types> (foo `requires` bar `requires` bar) :: Property HasInfo
<interactive>:22:6:
No instance for (Requires (Property HasInfo) (Property HasInfo) x0)
arising from a use of `requires'
The type variable `x0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there is a potential instance available:
instance Requires
(Property HasInfo) (Property HasInfo) (Property HasInfo)
-- Defined at Propellor/Types.hs:167:10
Possible fix:
add an instance declaration for
(Requires (Property HasInfo) (Property HasInfo) x0)
In the first argument of `requires', namely `foo `requires` bar'
In the expression:
(foo `requires` bar `requires` bar) :: Property HasInfo
In an equation for `it':
it = (foo `requires` bar `requires` bar) :: Property HasInfo
<interactive>:22:21:
No instance for (Requires x0 (Property HasInfo) (Property HasInfo))
arising from a use of `requires'
The type variable `x0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Requires
(Property NoInfo) (Property HasInfo) (Property HasInfo)
-- Defined at Propellor/Types.hs:175:10
instance Requires
(Property HasInfo) (Property HasInfo) (Property HasInfo)
-- Defined at Propellor/Types.hs:167:10
Possible fix:
add an instance declaration for
(Requires x0 (Property HasInfo) (Property HasInfo))
In the expression:
(foo `requires` bar `requires` bar) :: Property HasInfo
In an equation for `it':
it = (foo `requires` bar `requires` bar) :: Property HasInfo
*Propellor.Types> (((foo `requires` bar) :: Property HasInfo) `requires` bar) :: Property HasInfo
property "foo"
Yuggh!
Diffstat (limited to 'src/Propellor/Info.hs')
| -rw-r--r-- | src/Propellor/Info.hs | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/src/Propellor/Info.hs b/src/Propellor/Info.hs index 6d85cb74..1d8e7ab2 100644 --- a/src/Propellor/Info.hs +++ b/src/Propellor/Info.hs @@ -12,13 +12,13 @@ import Data.Maybe import Data.Monoid import Control.Applicative -pureInfoProperty :: Desc -> Info -> Property +pureInfoProperty :: Desc -> Info -> Property HasInfo pureInfoProperty desc i = mkProperty ("has " ++ desc) (return NoChange) i mempty askInfo :: (Info -> Val a) -> Propellor (Maybe a) askInfo f = asks (fromVal . f . hostInfo) -os :: System -> Property +os :: System -> Property HasInfo os system = pureInfoProperty ("Operating " ++ show system) $ mempty { _os = Val system } @@ -34,11 +34,11 @@ getOS = askInfo _os -- When propellor --spin is used to deploy a host, it checks -- if the host's IP Property matches the DNS. If the DNS is missing or -- out of date, the host will instead be contacted directly by IP address. -ipv4 :: String -> Property +ipv4 :: String -> Property HasInfo ipv4 = addDNS . Address . IPv4 -- | Indidate that a host has an AAAA record in the DNS. -ipv6 :: String -> Property +ipv6 :: String -> Property HasInfo ipv6 = addDNS . Address . IPv6 -- | Indicates another name for the host in the DNS. @@ -47,7 +47,7 @@ ipv6 = addDNS . Address . IPv6 -- to use their address, rather than using a CNAME. This avoids various -- problems with CNAMEs, and also means that when multiple hosts have the -- same alias, a DNS round-robin is automatically set up. -alias :: Domain -> Property +alias :: Domain -> Property HasInfo alias d = pureInfoProperty ("alias " ++ d) $ mempty { _aliases = S.singleton d -- A CNAME is added here, but the DNS setup code converts it to an @@ -55,7 +55,7 @@ alias d = pureInfoProperty ("alias " ++ d) $ mempty , _dns = S.singleton $ CNAME $ AbsDomain d } -addDNS :: Record -> Property +addDNS :: Record -> Property HasInfo addDNS r = pureInfoProperty (rdesc r) $ mempty { _dns = S.singleton r } where rdesc (CNAME d) = unwords ["alias", ddesc d] |
