onent { 29 def powerConfig: PowerConfig 30 } 31 trait Appliance extends DeviceComponent with PowerComponent 32 object Appliance { 33 val appliance = Reader[Appliance,Appliance](identity) 34 val onOffDevice = appliance map {_.onOffDevice} 35 val sensorDevice = appliance map {_.sensorDevice} 36 val powerConfig = appliance map {_.powerConfig} 37 } 38 object OnOffDevice { 39 import Appliance.onOffDevice 40 def on: Reader[Appliance,String] = onOffDevice map { _.on } 41 def off: Reader[Appliance,String] = onOffDevice map { _.off } 42 } 43 object SensorDevice { 44 import Appliance.sensorDevice 45 def isCoffeePresent: Reader[Appliance,Boolean] = sensorDevice map { _.isCoffeePresent } 46 } 47 object PowerConfig { 48 import Appliance.powerConfig 49 def getPowerVolts(country: String) = powerConfig map {_.getPowerVolts(country)} 50 def isUSStandard(volts: Int) = powerConfig map {_.isUSStandard(volts)} 51 } 52 object OnOffService { 53 def on = for { 54 ison <- OnOffDevice.on 55 } yield ison 56 def off = for { 57 isoff <- OnOffDevice.off 58 } yield isoff 59 } 60 object SensorService { 61 def isCoffeePresent = for { 62 hasCoffee <- SensorDevice.isCoffeePresent 63 } yield hasCoffee 64 } 65 object PowerService { 66 def isUSStandard(country: String) = for { 67 is110v <- PowerConfig.getPowerVolts(country) 68 isUSS <- PowerConfig.isUSStandard(is110v) 69 } yield isUSS 70 } 71 class OnOffDeviceImpl extends OnOffDevice { 72 def on = "SomeDevice.On"
73 def off = "SomeDevice.Off"
74 } 75 class SensorDeviceImpl extends SensorDevice { 76 def isCoffeePresent = true
77 } 78 class PowerConfigImpl extends PowerConfig { 79 def getPowerVolts(country: String) = country match { 80 case "USA" => 110
81 case "UK" => 220
82 case "HK" => 220
83 case "CHN" => 110
84 case _ => 0
85 } 86 def isUSStandard(volts: Int) = volts === 110
87 } 88 object MockOnOffDevice extends OnOffDeviceImpl 89 object MockSensorDevice extends SensorDeviceImpl 90 object MockPowerConfig extends PowerConfigImpl 91 trait OnOffFunctions extends OnOffComponent { 92 def onOffDevice = MockOnOffDevice 93 } 94 trait SensorFunctions extends SensorComponent { 95 def sensorDevice = MockSensorDevice 96 } 97 trait DeviceFunctions extends DeviceComponent { 98 def onOffDevice = MockOnOffDevice 99 def sensorDevice = MockSensorDevice 100 } 101 trait PowerFunctions extends PowerComponent { 102 def powerConfig = MockPowerConfig 103 } 104 object MockAppliance extends Appliance with DeviceFunctions with PowerFunctions 105 def trigger =
106 if ((PowerService.isUSStandard("CHN")(MockAppliance)) 107 && (SensorService.isCoffeePresent(MockAppliance))) 108 OnOffService.on(MockAppliance) 109 else
110 OnOffService.off(MockAppliance) //> trigger: => scalaz.Id.Id[String]
111 trigger //> res0: scalaz.Id.Id[String] = SomeDevice.On
112 }
|